From a71bfc249d3f814d7d659fe5cf4cb582483e8938 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 10 Apr 2019 18:47:14 -0400 Subject: compiler-rt: better way to do the ABI required on Windows This removes the compiler_rt.setXmm0 hack. Instead, for the functions that use i128 or u128 in their parameter and return types, we use `@Vector(2, u64)` which generates the LLVM IR `<2 x i64>` type that matches what Clang generates for `typedef int ti_int __attribute__ ((mode (TI)))` when targeting Windows x86_64. --- src/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 568344fc09..7d21787809 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -424,7 +424,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) { + if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->is_dynamic) { LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass); } } -- cgit v1.2.3 From 5f8dbcac0669973b0d0f07ce6777dcd4456676dd Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Thu, 11 Apr 2019 15:29:13 -0500 Subject: wasm: disable error ret tracing --- src/codegen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 7d21787809..7e85fa238a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7953,7 +7953,8 @@ static void init(CodeGen *g) { } } - g->have_err_ret_tracing = g->build_mode != BuildModeFastRelease && g->build_mode != BuildModeSmallRelease; + bool is_wasm = g->zig_target->arch == ZigLLVM_wasm32 || g->zig_target->arch == ZigLLVM_wasm64; + g->have_err_ret_tracing = !is_wasm && g->build_mode != BuildModeFastRelease && g->build_mode != BuildModeSmallRelease; define_builtin_fns(g); Error err; -- cgit v1.2.3 From 63f2e96eeaaa032ffa9ff11a4a632d8032883233 Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Fri, 12 Apr 2019 10:54:15 -0500 Subject: wasm: use .wasm ext for exe --- src/codegen.cpp | 3 +-- src/target.cpp | 6 ++++++ src/target.hpp | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 7e85fa238a..7d280b7ad1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7953,8 +7953,7 @@ static void init(CodeGen *g) { } } - bool is_wasm = g->zig_target->arch == ZigLLVM_wasm32 || g->zig_target->arch == ZigLLVM_wasm64; - g->have_err_ret_tracing = !is_wasm && g->build_mode != BuildModeFastRelease && g->build_mode != BuildModeSmallRelease; + g->have_err_ret_tracing = !target_is_wasm(g->zig_target) && g->build_mode != BuildModeFastRelease && g->build_mode != BuildModeSmallRelease; define_builtin_fns(g); Error err; diff --git a/src/target.cpp b/src/target.cpp index 3b4265359c..7d66761a16 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -965,6 +965,8 @@ const char *target_exe_file_ext(const ZigTarget *target) { return ".exe"; } else if (target->os == OsUefi) { return ".efi"; + } else if (target_is_wasm(target)) { + return ".wasm"; } else { return ""; } @@ -1365,6 +1367,10 @@ bool target_is_musl(const ZigTarget *target) { return target->os == OsLinux && target_abi_is_musl(target->abi); } +bool target_is_wasm(const ZigTarget *target) { + return target->arch == ZigLLVM_wasm32 || target->arch == ZigLLVM_wasm64; +} + ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) { switch (os) { case OsFreestanding: diff --git a/src/target.hpp b/src/target.hpp index 4a0264c2b1..0e3180bb2c 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -170,6 +170,7 @@ bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi); bool target_abi_is_musl(ZigLLVM_EnvironmentType abi); bool target_is_glibc(const ZigTarget *target); bool target_is_musl(const ZigTarget *target); +bool target_is_wasm(const ZigTarget *target); uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch); -- cgit v1.2.3 From 27253f09b6586ca602ebc64e21e48f5afa3464d9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 14 Apr 2019 11:00:37 -0400 Subject: organize how the single threaded option is passed around --- src/all_types.hpp | 1 + src/codegen.cpp | 27 +++++++++++++++++++++++++-- src/main.cpp | 14 +++++--------- 3 files changed, 31 insertions(+), 11 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index 39bccddc3f..5a5c1cfda4 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1856,6 +1856,7 @@ struct CodeGen { bool strip_debug_symbols; bool is_test_build; bool is_single_threaded; + bool want_single_threaded; bool linker_rdynamic; bool each_lib_rpath; bool is_dummy_so; diff --git a/src/codegen.cpp b/src/codegen.cpp index 7d280b7ad1..332eab59b9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7337,9 +7337,26 @@ static bool detect_pic(CodeGen *g) { zig_unreachable(); } +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 !target_is_wasm(g->zig_target) && + g->build_mode != BuildModeFastRelease && + g->build_mode != BuildModeSmallRelease; +} + Buf *codegen_generate_builtin_source(CodeGen *g) { 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); Buf *contents = buf_alloc(); @@ -7844,6 +7861,12 @@ static void init(CodeGen *g) { 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); + + if (target_is_single_threaded(g->zig_target)) { + g->is_single_threaded = true; + } if (g->is_test_build) { g->subsystem = TargetSubsystemConsole; @@ -7953,8 +7976,6 @@ static void init(CodeGen *g) { } } - g->have_err_ret_tracing = !target_is_wasm(g->zig_target) && g->build_mode != BuildModeFastRelease && g->build_mode != BuildModeSmallRelease; - define_builtin_fns(g); Error err; if ((err = define_builtin_compile_vars(g))) { @@ -9268,6 +9289,8 @@ void codegen_build_and_link(CodeGen *g) { 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); detect_libc(g); detect_dynamic_linker(g); diff --git a/src/main.cpp b/src/main.cpp index e571e1ae62..5123512d1c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -450,7 +450,7 @@ int main(int argc, char **argv) { int runtime_args_start = -1; bool system_linker_hack = false; TargetSubsystem subsystem = TargetSubsystemAuto; - bool is_single_threaded = false; + bool want_single_threaded = false; bool disable_gen_h = false; Buf *override_std_dir = nullptr; Buf *main_pkg_path = nullptr; @@ -590,7 +590,7 @@ int main(int argc, char **argv) { CodeGen *g = codegen_create(main_pkg_path, fmt_runner_path, &target, OutTypeExe, BuildModeDebug, get_zig_lib_dir(), nullptr, nullptr, cache_dir_buf); g->valgrind_support = valgrind_support; - g->is_single_threaded = true; + g->want_single_threaded = true; codegen_set_out_name(g, buf_create_from_str("fmt")); g->enable_cache = true; @@ -671,7 +671,7 @@ int main(int argc, char **argv) { } else if (strcmp(arg, "--system-linker-hack") == 0) { system_linker_hack = true; } else if (strcmp(arg, "--single-threaded") == 0) { - is_single_threaded = true; + want_single_threaded = true; } else if (strcmp(arg, "--disable-gen-h") == 0) { disable_gen_h = true; } else if (strcmp(arg, "--test-cmd-bin") == 0) { @@ -921,10 +921,6 @@ int main(int argc, char **argv) { } } - if (target_is_single_threaded(&target)) { - is_single_threaded = true; - } - if (output_dir != nullptr && enable_cache == CacheOptOn) { fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n"); return print_error_usage(arg0); @@ -966,7 +962,7 @@ int main(int argc, char **argv) { out_type, build_mode, get_zig_lib_dir(), override_std_dir, nullptr, nullptr); g->valgrind_support = valgrind_support; g->want_pic = want_pic; - g->is_single_threaded = is_single_threaded; + g->want_single_threaded = want_single_threaded; Buf *builtin_source = codegen_generate_builtin_source(g); if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) { fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout))); @@ -1064,7 +1060,7 @@ int main(int argc, char **argv) { codegen_set_out_name(g, buf_out_name); codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); codegen_set_is_test(g, cmd == CmdTest); - g->is_single_threaded = is_single_threaded; + g->want_single_threaded = want_single_threaded; codegen_set_linker_script(g, linker_script); if (each_lib_rpath) codegen_set_each_lib_rpath(g, each_lib_rpath); -- cgit v1.2.3 From a0d2185199e7723aabc38cacd83d6a140f12e01d Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Mon, 15 Apr 2019 17:00:04 -0500 Subject: wasm: add wasm-import-module attr to extern --- src/codegen.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 332eab59b9..88f0f739b6 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -495,6 +495,14 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { auto entry = g->exported_symbol_names.maybe_get(symbol_name); if (entry == nullptr) { fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type); + + if (target_is_wasm(g->zig_target)) { + assert(fn_table_entry->proto_node->type == NodeTypeFnProto); + AstNodeFnProto *fn_proto = &fn_table_entry->proto_node->data.fn_proto; + if (fn_proto-> is_extern && fn_proto->lib_name != nullptr ) { + addLLVMFnAttrStr(fn_table_entry->llvm_value, "wasm-import-module", buf_ptr(fn_proto->lib_name)); + } + } } else { assert(entry->value->id == TldIdFn); TldFn *tld_fn = reinterpret_cast(entry->value); -- cgit v1.2.3 From 579dd7411462a1359a08e8b4c0b4b9765d54a563 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 15 Apr 2019 20:17:06 -0400 Subject: fix Debug mode when error return tracing is off Previously the code for generating a panic crash expected one of the parameters to be the error return trace. Now it does not expect that parameter when g->have_err_ret_tracing is false. Closes #2276 --- src/codegen.cpp | 59 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 17 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 88f0f739b6..277d6a447f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1549,11 +1549,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { LLVMValueRef offset_buf_ptr = LLVMConstInBoundsGEP(global_array, offset_ptr_indices, 2); Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false); - LLVMTypeRef arg_types[] = { - get_llvm_type(g, g->ptr_to_stack_trace_type), - get_llvm_type(g, g->err_tag_type), - }; - LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false); + LLVMTypeRef fn_type_ref; + if (g->have_err_ret_tracing) { + LLVMTypeRef arg_types[] = { + get_llvm_type(g, g->ptr_to_stack_trace_type), + get_llvm_type(g, g->err_tag_type), + }; + fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false); + } else { + LLVMTypeRef arg_types[] = { + get_llvm_type(g, g->err_tag_type), + }; + fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 1, false); + } LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref); addLLVMFnAttr(fn_val, "noreturn"); addLLVMFnAttr(fn_val, "cold"); @@ -1575,7 +1583,15 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { LLVMPositionBuilderAtEnd(g->builder, entry_block); ZigLLVMClearCurrentDebugLocation(g->builder); - LLVMValueRef err_val = LLVMGetParam(fn_val, 1); + LLVMValueRef err_ret_trace_arg; + LLVMValueRef err_val; + if (g->have_err_ret_tracing) { + err_ret_trace_arg = LLVMGetParam(fn_val, 0); + err_val = LLVMGetParam(fn_val, 1); + } else { + err_ret_trace_arg = nullptr; + err_val = LLVMGetParam(fn_val, 0); + } LLVMValueRef err_table_indices[] = { LLVMConstNull(g->builtin_types.entry_usize->llvm_type), @@ -1597,7 +1613,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, ""); gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type); - gen_panic(g, global_slice, LLVMGetParam(fn_val, 0)); + gen_panic(g, global_slice, err_ret_trace_arg); LLVMPositionBuilderAtEnd(g->builder, prev_block); LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); @@ -1633,17 +1649,26 @@ static LLVMValueRef get_cur_err_ret_trace_val(CodeGen *g, Scope *scope) { static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *scope) { LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g); - LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, scope); - if (err_ret_trace_val == nullptr) { - ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); - err_ret_trace_val = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type)); + LLVMValueRef call_instruction; + if (g->have_err_ret_tracing) { + LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, scope); + if (err_ret_trace_val == nullptr) { + ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); + err_ret_trace_val = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type)); + } + LLVMValueRef args[] = { + err_ret_trace_val, + err_val, + }; + call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, + get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, ""); + } else { + LLVMValueRef args[] = { + err_val, + }; + call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 1, + get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, ""); } - LLVMValueRef args[] = { - err_ret_trace_val, - err_val, - }; - LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, get_llvm_cc(g, CallingConventionUnspecified), - ZigLLVM_FnInlineAuto, ""); LLVMSetTailCall(call_instruction, true); LLVMBuildUnreachable(g->builder); } -- cgit v1.2.3 From 4e2f6ebf398f5d84aa630c4a9ab40c0de3980a72 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 16 Apr 2019 12:06:14 -0400 Subject: freestanding target adds -ffrestanding to cc parameters closes #2287 --- src/codegen.cpp | 3 +++ src/translate_c.cpp | 3 +++ 2 files changed, 6 insertions(+) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 277d6a447f..8eea4e87f1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8531,6 +8531,9 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { args.append("-target"); args.append(buf_ptr(&g->triple_str)); } + if (g->zig_target->os == OsFreestanding) { + args.append("-ffreestanding"); + } if (!g->strip_debug_symbols) { args.append("-g"); diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 659b5ef0cc..43783cf1c0 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4988,6 +4988,9 @@ Error parse_h_file(AstNode **out_root_node, ZigList *errors, const c clang_argv.append("-target"); clang_argv.append(buf_ptr(&c->codegen->triple_str)); } + if (c->codegen->zig_target->os == OsFreestanding) { + clang_argv.append("-ffreestanding"); + } clang_argv.append(target_file); -- cgit v1.2.3 From 89763c9a0d9a838439bcc6cd996c0ff2d3d0daca Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 16 Apr 2019 16:47:47 -0400 Subject: stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964 --- CMakeLists.txt | 61 +++++++++++++++++++----- build.zig | 19 ++++++++ src-self-hosted/main.zig | 18 +------ src-self-hosted/stage1.zig | 27 +++++++++++ src-self-hosted/translate_c.zig | 8 ++++ src/codegen.cpp | 22 +++++++-- src/codegen.hpp | 2 +- src/compiler.cpp | 8 ++-- src/compiler.hpp | 4 +- src/main.cpp | 101 ++++++++++++++++++++++++---------------- src/userland.cpp | 10 ++++ src/userland.h | 23 +++++++++ std/build.zig | 17 +++++++ std/special/build_runner.zig | 30 ++++++++---- 14 files changed, 261 insertions(+), 89 deletions(-) create mode 100644 src-self-hosted/stage1.zig create mode 100644 src-self-hosted/translate_c.zig create mode 100644 src/userland.cpp create mode 100644 src/userland.h (limited to 'src/codegen.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 38bd9a2a7d..1bc9d2f043 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -407,6 +407,12 @@ set(SOFTFLOAT_LIBRARIES embedded_softfloat) find_package(Threads) +# CMake doesn't let us create an empty executable, so we hang on to this one separately. +set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp") + +# This is our shim which will be replaced by libuserland written in Zig. +set(ZIG1_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp") + set(ZIG_SOURCES "${CMAKE_SOURCE_DIR}/src/analyze.cpp" "${CMAKE_SOURCE_DIR}/src/ast_render.cpp" @@ -423,7 +429,6 @@ set(ZIG_SOURCES "${CMAKE_SOURCE_DIR}/src/ir_print.cpp" "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp" "${CMAKE_SOURCE_DIR}/src/link.cpp" - "${CMAKE_SOURCE_DIR}/src/main.cpp" "${CMAKE_SOURCE_DIR}/src/os.cpp" "${CMAKE_SOURCE_DIR}/src/parser.cpp" "${CMAKE_SOURCE_DIR}/src/range_set.cpp" @@ -6635,19 +6640,19 @@ add_library(zig_cpp STATIC ${ZIG_CPP_SOURCES}) set_target_properties(zig_cpp PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} ) +install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}") add_library(opt_c_util STATIC ${OPTIMIZED_C_SOURCES}) set_target_properties(opt_c_util PROPERTIES COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}" ) -add_executable(zig ${ZIG_SOURCES}) -set_target_properties(zig PROPERTIES +add_library(compiler STATIC ${ZIG_SOURCES}) +set_target_properties(compiler PROPERTIES COMPILE_FLAGS ${EXE_CFLAGS} LINK_FLAGS ${EXE_LDFLAGS} ) - -target_link_libraries(zig LINK_PUBLIC +target_link_libraries(compiler LINK_PUBLIC zig_cpp opt_c_util ${SOFTFLOAT_LIBRARIES} @@ -6656,24 +6661,58 @@ target_link_libraries(zig LINK_PUBLIC ${LLVM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) - if(NOT MSVC) - target_link_libraries(zig LINK_PUBLIC ${LIBXML2}) + target_link_libraries(compiler LINK_PUBLIC ${LIBXML2}) endif() if(MINGW) - target_link_libraries(zig LINK_PUBLIC ${Z3_LIBRARIES}) + target_link_libraries(compiler LINK_PUBLIC ${Z3_LIBRARIES}) endif() if(ZIG_DIA_GUIDS_LIB) - target_link_libraries(zig LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB}) + target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB}) endif() if(MSVC OR MINGW) - target_link_libraries(zig LINK_PUBLIC version) + target_link_libraries(compiler LINK_PUBLIC version) +endif() + +add_executable(zig1 "${ZIG_MAIN_SRC}" "${ZIG1_SHIM_SRC}") +set_target_properties(zig1 PROPERTIES + COMPILE_FLAGS ${EXE_CFLAGS} + LINK_FLAGS ${EXE_LDFLAGS} +) +target_link_libraries(zig1 compiler) + +if(WIN32) + set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.lib") +elseif(APPLE) + set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.o") +else() + set(LIBUSERLAND "${CMAKE_BINARY_DIR}/libuserland.a") endif() +add_custom_command( + OUTPUT "${LIBUSERLAND}" + COMMAND zig1 ARGS build + --override-std-dir std + --override-lib-dir "${CMAKE_SOURCE_DIR}" + libuserland + "-Doutput-dir=${CMAKE_BINARY_DIR}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + DEPENDS + "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig" + "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig" +) +add_custom_target(userland_target DEPENDS "${LIBUSERLAND}") +add_executable(zig "${ZIG_MAIN_SRC}") +set_target_properties(zig PROPERTIES + COMPILE_FLAGS ${EXE_CFLAGS} + LINK_FLAGS ${EXE_LDFLAGS} +) +target_link_libraries(zig compiler "${LIBUSERLAND}") +add_dependencies(zig userland_target) install(TARGETS zig DESTINATION bin) -install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}") + foreach(file ${ZIG_C_HEADER_FILES}) get_filename_component(file_dir "${C_HEADERS_DEST}/${file}" DIRECTORY) diff --git a/build.zig b/build.zig index 2dc9c671ec..a53743ca3c 100644 --- a/build.zig +++ b/build.zig @@ -65,6 +65,8 @@ pub fn build(b: *Builder) !void { b.default_step.dependOn(&exe.step); + addLibUserlandStep(b); + const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false; const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release; const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release; @@ -380,3 +382,20 @@ const Context = struct { dia_guids_lib: []const u8, llvm: LibraryDep, }; + +fn addLibUserlandStep(b: *Builder) void { + const artifact = if (builtin.os == .macosx) + b.addObject("userland", "src-self-hosted/stage1.zig") + else + b.addStaticLibrary("userland", "src-self-hosted/stage1.zig"); + artifact.disable_gen_h = true; + const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1"); + libuserland_step.dependOn(&artifact.step); + + const output_dir = b.option( + []const u8, + "output-dir", + "For libuserland step, where to put the output", + ) orelse return; + artifact.setOutputDir(output_dir); +} diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 4c3edf6d5d..361afc80e3 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -858,23 +858,7 @@ fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void { try stdout.write(usage); } -const info_zen = - \\ - \\ * Communicate intent precisely. - \\ * Edge cases matter. - \\ * Favor reading code over writing code. - \\ * Only one obvious way to do things. - \\ * Runtime crashes are better than bugs. - \\ * Compile errors are better than runtime crashes. - \\ * Incremental improvements. - \\ * Avoid local maximums. - \\ * Reduce the amount one must remember. - \\ * Minimize energy spent on coding style. - \\ * Together we serve end users. - \\ - \\ -; - +const info_zen = @import("stage1.zig").info_zen; fn cmdZen(allocator: *Allocator, args: []const []const u8) !void { try stdout.write(info_zen); } diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig new file mode 100644 index 0000000000..bf400113e4 --- /dev/null +++ b/src-self-hosted/stage1.zig @@ -0,0 +1,27 @@ +// This is Zig code that is used by both stage1 and stage2. +// The prototypes in src/userland.h must match these definitions. +comptime { + _ = @import("translate_c.zig"); +} + +pub const info_zen = + \\ + \\ * Communicate intent precisely. + \\ * Edge cases matter. + \\ * Favor reading code over writing code. + \\ * Only one obvious way to do things. + \\ * Runtime crashes are better than bugs. + \\ * Compile errors are better than runtime crashes. + \\ * Incremental improvements. + \\ * Avoid local maximums. + \\ * Reduce the amount one must remember. + \\ * Minimize energy spent on coding style. + \\ * Together we serve end users. + \\ + \\ +; + +export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { + ptr.* = &info_zen; + len.* = info_zen.len; +} diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig new file mode 100644 index 0000000000..e182a5a994 --- /dev/null +++ b/src-self-hosted/translate_c.zig @@ -0,0 +1,8 @@ +// This is the userland implementation of translate-c which will be used by both stage1 +// and stage2. Currently it's not used by anything, as it's not feature complete. + +const std = @import("std"); + +export fn stage2_translate_c() void { + std.debug.panic("unimplemented"); +} diff --git a/src/codegen.cpp b/src/codegen.cpp index 8eea4e87f1..33049abd62 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -19,6 +19,7 @@ #include "target.hpp" #include "util.hpp" #include "zig_llvm.h" +#include "userland.h" #include #include @@ -92,7 +93,7 @@ static const char *symbols_that_llvm_depends_on[] = { }; CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, - OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, Buf *override_std_dir, + OutType out_type, BuildMode build_mode, Buf *override_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc, Buf *cache_dir) { CodeGen *g = allocate(1); @@ -100,19 +101,24 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget codegen_add_time_event(g, "Initialize"); g->libc = libc; - g->zig_lib_dir = zig_lib_dir; 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; + } + if (override_std_dir == nullptr) { g->zig_std_dir = buf_alloc(); - os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir); + os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir); } else { g->zig_std_dir = override_std_dir; } g->zig_c_headers_dir = buf_alloc(); - os_path_join(zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir); + 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; @@ -8147,7 +8153,7 @@ static void detect_libc(CodeGen *g) { } } -AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) { +AstNode *codegen_translate_c(CodeGen *g, Buf *full_path, bool use_userland_implementation) { Buf *src_basename = buf_alloc(); Buf *src_dirname = buf_alloc(); os_path_split(full_path, src_dirname, src_basename); @@ -8159,6 +8165,12 @@ AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) { init(g); + if (use_userland_implementation) { + // TODO improve this + stage2_translate_c(); + zig_panic("TODO"); + } + ZigList errors = {0}; AstNode *root_node; Error err = parse_h_file(&root_node, &errors, buf_ptr(full_path), g, nullptr); diff --git a/src/codegen.hpp b/src/codegen.hpp index 3befca2de5..d6149bf5d2 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -50,7 +50,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c void codegen_add_assembly(CodeGen *g, Buf *path); void codegen_add_object(CodeGen *g, Buf *object_path); -AstNode *codegen_translate_c(CodeGen *g, Buf *path); +AstNode *codegen_translate_c(CodeGen *g, Buf *path, bool use_userland_implementation); Buf *codegen_generate_builtin_source(CodeGen *g); diff --git a/src/compiler.cpp b/src/compiler.cpp index af62173db7..8bfe87bfcd 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -179,24 +179,24 @@ Buf *get_zig_lib_dir(void) { return &saved_lib_dir; } -Buf *get_zig_std_dir() { +Buf *get_zig_std_dir(Buf *zig_lib_dir) { if (saved_std_dir.list.length != 0) { return &saved_std_dir; } buf_resize(&saved_std_dir, 0); - os_path_join(get_zig_lib_dir(), buf_create_from_str("std"), &saved_std_dir); + os_path_join(zig_lib_dir, buf_create_from_str("std"), &saved_std_dir); return &saved_std_dir; } -Buf *get_zig_special_dir() { +Buf *get_zig_special_dir(Buf *zig_lib_dir) { if (saved_special_dir.list.length != 0) { return &saved_special_dir; } buf_resize(&saved_special_dir, 0); - os_path_join(get_zig_std_dir(), buf_sprintf("special"), &saved_special_dir); + os_path_join(get_zig_std_dir(zig_lib_dir), buf_sprintf("special"), &saved_special_dir); return &saved_special_dir; } diff --git a/src/compiler.hpp b/src/compiler.hpp index f2788b9998..4d682ba2fa 100644 --- a/src/compiler.hpp +++ b/src/compiler.hpp @@ -16,7 +16,7 @@ Error get_compiler_id(Buf **result); Buf *get_self_dynamic_linker_path(void); Buf *get_zig_lib_dir(void); -Buf *get_zig_special_dir(void); -Buf *get_zig_std_dir(void); +Buf *get_zig_special_dir(Buf *zig_lib_dir); +Buf *get_zig_std_dir(Buf *zig_lib_dir); #endif diff --git a/src/main.cpp b/src/main.cpp index 5123512d1c..03cf3aad68 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ #include "os.hpp" #include "target.hpp" #include "libc_installation.hpp" +#include "userland.h" #include @@ -40,6 +41,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " libc [paths_file] Display native libc paths file or validate one\n" " run [source] [-- [args]] create executable and run immediately\n" " translate-c [source] convert c code to zig code\n" + " translate-c-2 [source] experimental self-hosted translate-c\n" " targets list available compilation targets\n" " test [source] create and run a test build\n" " version print version number and exit\n" @@ -131,19 +133,6 @@ static int print_libc_usage(const char *arg0, FILE *file, int return_code) { return return_code; } -static const char *ZIG_ZEN = "\n" -" * Communicate intent precisely.\n" -" * Edge cases matter.\n" -" * Favor reading code over writing code.\n" -" * Only one obvious way to do things.\n" -" * Runtime crashes are better than bugs.\n" -" * Compile errors are better than runtime crashes.\n" -" * Incremental improvements.\n" -" * Avoid local maximums.\n" -" * Reduce the amount one must remember.\n" -" * Minimize energy spent on coding style.\n" -" * Together we serve end users.\n"; - static bool arch_available_in_llvm(ZigLLVM_ArchType arch) { LLVMTargetRef target_ref; char *err_msg = nullptr; @@ -211,6 +200,7 @@ enum Cmd { CmdTargets, CmdTest, CmdTranslateC, + CmdTranslateCUserland, CmdVersion, CmdZen, CmdLibC, @@ -324,7 +314,7 @@ int main(int argc, char **argv) { return print_error_usage(arg0); } Buf *cmd_template_path = buf_alloc(); - os_path_join(get_zig_special_dir(), buf_create_from_str(init_cmd), cmd_template_path); + os_path_join(get_zig_special_dir(get_zig_lib_dir()), buf_create_from_str(init_cmd), cmd_template_path); Buf *build_zig_path = buf_alloc(); os_path_join(cmd_template_path, buf_create_from_str("build.zig"), build_zig_path); Buf *src_dir_path = buf_alloc(); @@ -453,6 +443,7 @@ int main(int argc, char **argv) { bool want_single_threaded = false; bool disable_gen_h = false; Buf *override_std_dir = nullptr; + Buf *override_lib_dir = nullptr; Buf *main_pkg_path = nullptr; ValgrindSupport valgrind_support = ValgrindSupportAuto; WantPIC want_pic = WantPICAuto; @@ -486,13 +477,27 @@ int main(int argc, char **argv) { } else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) { cache_dir = argv[i + 1]; i += 1; + } else if (i + 1 < argc && strcmp(argv[i], "--override-std-dir") == 0) { + override_std_dir = buf_create_from_str(argv[i + 1]); + i += 1; + + args.append("--override-std-dir"); + args.append(buf_ptr(override_std_dir)); + } else if (i + 1 < argc && strcmp(argv[i], "--override-lib-dir") == 0) { + override_lib_dir = buf_create_from_str(argv[i + 1]); + i += 1; + + args.append("--override-lib-dir"); + args.append(buf_ptr(override_lib_dir)); } else { args.append(argv[i]); } } + Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir; + Buf *build_runner_path = buf_alloc(); - os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path); + os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); ZigTarget target; get_native_target(&target); @@ -512,7 +517,7 @@ int main(int argc, char **argv) { } CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe, - BuildModeDebug, get_zig_lib_dir(), override_std_dir, nullptr, &full_cache_dir); + BuildModeDebug, override_lib_dir, override_std_dir, nullptr, &full_cache_dir); g->valgrind_support = valgrind_support; g->enable_time_report = timing_info; codegen_set_out_name(g, buf_create_from_str("build")); @@ -532,23 +537,25 @@ int main(int argc, char **argv) { "Usage: %s build [options]\n" "\n" "General Options:\n" - " --help Print this help and exit\n" - " --verbose Print commands before executing them\n" - " --prefix [path] Override default install prefix\n" - " --search-prefix [path] Add a path to look for binaries, libraries, headers\n" + " --help Print this help and exit\n" + " --verbose Print commands before executing them\n" + " --prefix [path] Override default install prefix\n" + " --search-prefix [path] Add a path to look for binaries, libraries, headers\n" "\n" "Project-specific options become available when the build file is found.\n" "\n" "Advanced Options:\n" - " --build-file [file] Override path to build.zig\n" - " --cache-dir [path] Override path to cache directory\n" - " --verbose-tokenize Enable compiler debug output for tokenization\n" - " --verbose-ast Enable compiler debug output for parsing into an AST\n" - " --verbose-link Enable compiler debug output for linking\n" - " --verbose-ir Enable compiler debug output for Zig IR\n" - " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n" - " --verbose-cimport Enable compiler debug output for C imports\n" - " --verbose-cc Enable compiler debug output for C compilation\n" + " --build-file [file] Override path to build.zig\n" + " --cache-dir [path] Override path to cache directory\n" + " --override-std-dir [arg] Override path to Zig standard library\n" + " --override-lib-dir [arg] Override path to Zig lib library\n" + " --verbose-tokenize Enable compiler debug output for tokenization\n" + " --verbose-ast Enable compiler debug output for parsing into an AST\n" + " --verbose-link Enable compiler debug output for linking\n" + " --verbose-ir Enable compiler debug output for Zig IR\n" + " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n" + " --verbose-cimport Enable compiler debug output for C imports\n" + " --verbose-cc Enable compiler debug output for C compilation\n" "\n" , zig_exe_path); return EXIT_SUCCESS; @@ -584,11 +591,12 @@ int main(int argc, char **argv) { init_all_targets(); ZigTarget target; get_native_target(&target); + Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir; Buf *fmt_runner_path = buf_alloc(); - os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path); + os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("fmt_runner.zig"), fmt_runner_path); Buf *cache_dir_buf = buf_create_from_str(cache_dir ? cache_dir : default_zig_cache_name); CodeGen *g = codegen_create(main_pkg_path, fmt_runner_path, &target, OutTypeExe, - BuildModeDebug, get_zig_lib_dir(), nullptr, nullptr, cache_dir_buf); + BuildModeDebug, zig_lib_dir, nullptr, nullptr, cache_dir_buf); g->valgrind_support = valgrind_support; g->want_single_threaded = true; codegen_set_out_name(g, buf_create_from_str("fmt")); @@ -757,6 +765,8 @@ int main(int argc, char **argv) { llvm_argv.append(argv[i]); } else if (strcmp(arg, "--override-std-dir") == 0) { override_std_dir = buf_create_from_str(argv[i]); + } else if (strcmp(arg, "--override-lib-dir") == 0) { + override_lib_dir = buf_create_from_str(argv[i]); } else if (strcmp(arg, "--main-pkg-path") == 0) { main_pkg_path = buf_create_from_str(argv[i]); } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) { @@ -867,6 +877,8 @@ int main(int argc, char **argv) { cmd = CmdLibC; } else if (strcmp(arg, "translate-c") == 0) { cmd = CmdTranslateC; + } else if (strcmp(arg, "translate-c-2") == 0) { + cmd = CmdTranslateCUserland; } else if (strcmp(arg, "test") == 0) { cmd = CmdTest; out_type = OutTypeExe; @@ -883,6 +895,7 @@ int main(int argc, char **argv) { case CmdBuild: case CmdRun: case CmdTranslateC: + case CmdTranslateCUserland: case CmdTest: case CmdLibC: if (!in_file) { @@ -959,7 +972,7 @@ int main(int argc, char **argv) { } case CmdBuiltin: { CodeGen *g = codegen_create(main_pkg_path, nullptr, &target, - out_type, build_mode, get_zig_lib_dir(), override_std_dir, nullptr, nullptr); + out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr); g->valgrind_support = valgrind_support; g->want_pic = want_pic; g->want_single_threaded = want_single_threaded; @@ -973,6 +986,7 @@ int main(int argc, char **argv) { case CmdRun: case CmdBuild: case CmdTranslateC: + case CmdTranslateCUserland: case CmdTest: { if (cmd == CmdBuild && !in_file && objects.length == 0 && asm_files.length == 0 && @@ -985,14 +999,16 @@ int main(int argc, char **argv) { " * --assembly argument\n" " * --c-source argument\n"); return print_error_usage(arg0); - } else if ((cmd == CmdTranslateC || cmd == CmdTest || cmd == CmdRun) && !in_file) { + } else if ((cmd == CmdTranslateC || cmd == CmdTranslateCUserland || + cmd == CmdTest || cmd == CmdRun) && !in_file) + { fprintf(stderr, "Expected source file argument.\n"); return print_error_usage(arg0); } assert(cmd != CmdBuild || out_type != OutTypeUnknown); - bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC); + bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC || cmd == CmdTranslateCUserland); if (cmd == CmdRun) { out_name = "run"; @@ -1026,7 +1042,8 @@ int main(int argc, char **argv) { return print_error_usage(arg0); } - Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf; + Buf *zig_root_source_file = (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) ? + nullptr : in_file_buf; if (cmd == CmdRun && buf_out_name == nullptr) { buf_out_name = buf_create_from_str("run"); @@ -1050,7 +1067,7 @@ int main(int argc, char **argv) { cache_dir_buf = buf_create_from_str(cache_dir); } CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode, - get_zig_lib_dir(), override_std_dir, libc, cache_dir_buf); + override_lib_dir, override_std_dir, libc, cache_dir_buf); if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2); g->valgrind_support = valgrind_support; g->want_pic = want_pic; @@ -1170,8 +1187,8 @@ int main(int argc, char **argv) { } else { zig_unreachable(); } - } else if (cmd == CmdTranslateC) { - AstNode *root_node = codegen_translate_c(g, in_file_buf); + } else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) { + AstNode *root_node = codegen_translate_c(g, in_file_buf, cmd == CmdTranslateCUserland); ast_render(g, stdout, root_node, 4); if (timing_info) codegen_print_timing_report(g, stderr); @@ -1229,9 +1246,13 @@ int main(int argc, char **argv) { case CmdVersion: printf("%s\n", ZIG_VERSION_STRING); return EXIT_SUCCESS; - case CmdZen: - printf("%s\n", ZIG_ZEN); + case CmdZen: { + const char *ptr; + size_t len; + stage2_zen(&ptr, &len); + fwrite(ptr, len, 1, stdout); return EXIT_SUCCESS; + } case CmdTargets: return print_target_list(stdout); case CmdNone: diff --git a/src/userland.cpp b/src/userland.cpp new file mode 100644 index 0000000000..25b1492290 --- /dev/null +++ b/src/userland.cpp @@ -0,0 +1,10 @@ +// This file is a shim for zig1. The real implementations of these are in +// src-self-hosted/stage1.zig + +#include "userland.h" + +void stage2_translate_c(void) {} +void stage2_zen(const char **ptr, size_t *len) { + *ptr = nullptr; + *len = 0; +} diff --git a/src/userland.h b/src/userland.h new file mode 100644 index 0000000000..92557ef994 --- /dev/null +++ b/src/userland.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef ZIG_USERLAND_H +#define ZIG_USERLAND_H + +#include + +#ifdef __cplusplus +#define ZIG_USERLAND_EXTERN_C extern "C" +#else +#define ZIG_USERLAND_EXTERN_C +#endif + +ZIG_USERLAND_EXTERN_C void stage2_translate_c(void); + +ZIG_USERLAND_EXTERN_C void stage2_zen(const char **ptr, size_t *len); + +#endif diff --git a/std/build.zig b/std/build.zig index 2bd4a9b08f..4d6c915438 100644 --- a/std/build.zig +++ b/std/build.zig @@ -50,6 +50,8 @@ pub const Builder = struct { build_root: []const u8, cache_root: []const u8, release_mode: ?builtin.Mode, + override_std_dir: ?[]const u8, + override_lib_dir: ?[]const u8, pub const CStd = enum { C89, @@ -133,6 +135,8 @@ pub const Builder = struct { }, .have_install_step = false, .release_mode = null, + .override_std_dir = null, + .override_lib_dir = null, }; self.detectNativeSystemPaths(); self.default_step = self.step("default", "Build the project"); @@ -939,6 +943,7 @@ pub const LibExeObjStep = struct { disable_gen_h: bool, c_std: Builder.CStd, override_std_dir: ?[]const u8, + override_lib_dir: ?[]const u8, main_pkg_path: ?[]const u8, exec_cmd_args: ?[]const ?[]const u8, name_prefix: []const u8, @@ -1039,6 +1044,7 @@ pub const LibExeObjStep = struct { .c_std = Builder.CStd.C99, .system_linker_hack = false, .override_std_dir = null, + .override_lib_dir = null, .main_pkg_path = null, .exec_cmd_args = null, .name_prefix = "", @@ -1528,6 +1534,17 @@ pub const LibExeObjStep = struct { if (self.override_std_dir) |dir| { try zig_args.append("--override-std-dir"); try zig_args.append(builder.pathFromRoot(dir)); + } else if (self.builder.override_std_dir) |dir| { + try zig_args.append("--override-std-dir"); + try zig_args.append(builder.pathFromRoot(dir)); + } + + if (self.override_lib_dir) |dir| { + try zig_args.append("--override-lib-dir"); + try zig_args.append(builder.pathFromRoot(dir)); + } else if (self.builder.override_lib_dir) |dir| { + try zig_args.append("--override-lib-dir"); + try zig_args.append(builder.pathFromRoot(dir)); } if (self.main_pkg_path) |dir| { diff --git a/std/special/build_runner.zig b/std/special/build_runner.zig index 56cfe3bcb5..dfc3838577 100644 --- a/std/special/build_runner.zig +++ b/std/special/build_runner.zig @@ -94,6 +94,16 @@ pub fn main() !void { return usageAndErr(&builder, false, try stderr_stream); }); builder.addSearchPrefix(search_prefix); + } else if (mem.eql(u8, arg, "--override-std-dir")) { + builder.override_std_dir = try unwrapArg(arg_it.next(allocator) orelse { + warn("Expected argument after --override-std-dir\n\n"); + return usageAndErr(&builder, false, try stderr_stream); + }); + } else if (mem.eql(u8, arg, "--override-lib-dir")) { + builder.override_lib_dir = try unwrapArg(arg_it.next(allocator) orelse { + warn("Expected argument after --override-lib-dir\n\n"); + return usageAndErr(&builder, false, try stderr_stream); + }); } else if (mem.eql(u8, arg, "--verbose-tokenize")) { builder.verbose_tokenize = true; } else if (mem.eql(u8, arg, "--verbose-ast")) { @@ -187,15 +197,17 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void { try out_stream.write( \\ \\Advanced Options: - \\ --build-file [file] Override path to build.zig - \\ --cache-dir [path] Override path to zig cache directory - \\ --verbose-tokenize Enable compiler debug output for tokenization - \\ --verbose-ast Enable compiler debug output for parsing into an AST - \\ --verbose-link Enable compiler debug output for linking - \\ --verbose-ir Enable compiler debug output for Zig IR - \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR - \\ --verbose-cimport Enable compiler debug output for C imports - \\ --verbose-cc Enable compiler debug output for C compilation + \\ --build-file [file] Override path to build.zig + \\ --cache-dir [path] Override path to zig cache directory + \\ --override-std-dir [arg] Override path to Zig standard library + \\ --override-lib-dir [arg] Override path to Zig lib directory + \\ --verbose-tokenize Enable compiler debug output for tokenization + \\ --verbose-ast Enable compiler debug output for parsing into an AST + \\ --verbose-link Enable compiler debug output for linking + \\ --verbose-ir Enable compiler debug output for Zig IR + \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR + \\ --verbose-cimport Enable compiler debug output for C imports + \\ --verbose-cc Enable compiler debug output for C compilation \\ ); } -- cgit v1.2.3 From 8ef7f6febb7132d7a1ee44199fd22006f326de5c Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Tue, 9 Apr 2019 19:16:51 -0500 Subject: remove Shebang (#!) support Closes: #2165 --- src/analyze.cpp | 2 +- src/cache_hash.cpp | 2 +- src/codegen.cpp | 6 +++--- src/libc_installation.cpp | 2 +- src/main.cpp | 4 ++-- src/os.cpp | 35 +++++------------------------------ src/os.hpp | 4 ++-- std/zig/ast.zig | 3 --- std/zig/parse.zig | 10 ---------- std/zig/parser_test.zig | 8 -------- std/zig/render.zig | 5 ----- 11 files changed, 15 insertions(+), 66 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index 2775c05b79..64cf8f2321 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -6072,7 +6072,7 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents) { if (g->enable_cache) { return cache_add_file_fetch(&g->cache_hash, resolved_path, contents); } else { - return os_fetch_file_path(resolved_path, contents, false); + return os_fetch_file_path(resolved_path, contents); } } diff --git a/src/cache_hash.cpp b/src/cache_hash.cpp index efb1a06b59..2a0810eced 100644 --- a/src/cache_hash.cpp +++ b/src/cache_hash.cpp @@ -469,7 +469,7 @@ Error cache_add_file(CacheHash *ch, Buf *path) { Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) { Error err; Buf *contents = buf_alloc(); - if ((err = os_fetch_file_path(dep_file_path, contents, false))) { + if ((err = os_fetch_file_path(dep_file_path, contents))) { if (verbose) { fprintf(stderr, "unable to read .d file: %s\n", err_str(err)); } diff --git a/src/codegen.cpp b/src/codegen.cpp index 33049abd62..6075fb6881 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7870,7 +7870,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { Buf *contents; if (hit) { contents = buf_alloc(); - if ((err = os_fetch_file_path(builtin_zig_path, contents, false))) { + 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)); exit(1); } @@ -8299,7 +8299,7 @@ static void gen_root_source(CodeGen *g) { Error err; // No need for using the caching system for this file fetch because it is handled // separately. - if ((err = os_fetch_file_path(resolved_path, source_code, true))) { + if ((err = os_fetch_file_path(resolved_path, source_code))) { fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err)); exit(1); } @@ -8374,7 +8374,7 @@ static void gen_global_asm(CodeGen *g) { Buf *asm_file = g->assembly_files.at(i); // No need to use the caching system for these fetches because they // are handled separately. - if ((err = os_fetch_file_path(asm_file, &contents, false))) { + if ((err = os_fetch_file_path(asm_file, &contents))) { zig_panic("Unable to read %s: %s", buf_ptr(asm_file), err_str(err)); } buf_append_buf(&g->global_asm, &contents); diff --git a/src/libc_installation.cpp b/src/libc_installation.cpp index 3ea17f1bdc..3e5f8b0d66 100644 --- a/src/libc_installation.cpp +++ b/src/libc_installation.cpp @@ -45,7 +45,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget bool found_keys[array_length(zig_libc_keys)] = {}; Buf *contents = buf_alloc(); - if ((err = os_fetch_file_path(libc_file, contents, false))) { + if ((err = os_fetch_file_path(libc_file, contents))) { if (err != ErrorFileNotFound && verbose) { fprintf(stderr, "Unable to read '%s': %s\n", buf_ptr(libc_file), err_str(err)); } diff --git a/src/main.cpp b/src/main.cpp index 03cf3aad68..8cbc9b0d8c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -331,7 +331,7 @@ int main(int argc, char **argv) { os_path_split(cwd, nullptr, cwd_basename); Buf *build_zig_contents = buf_alloc(); - if ((err = os_fetch_file_path(build_zig_path, build_zig_contents, false))) { + if ((err = os_fetch_file_path(build_zig_path, build_zig_contents))) { fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(build_zig_path), err_str(err)); return EXIT_FAILURE; } @@ -346,7 +346,7 @@ int main(int argc, char **argv) { } Buf *main_zig_contents = buf_alloc(); - if ((err = os_fetch_file_path(main_zig_path, main_zig_contents, false))) { + if ((err = os_fetch_file_path(main_zig_path, main_zig_contents))) { fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(main_zig_path), err_str(err)); return EXIT_FAILURE; } diff --git a/src/os.cpp b/src/os.cpp index 60c66908cc..49d56f2d5d 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -751,39 +751,15 @@ Buf os_path_resolve(Buf **paths_ptr, size_t paths_len) { #endif } -Error os_fetch_file(FILE *f, Buf *out_buf, bool skip_shebang) { +Error os_fetch_file(FILE *f, Buf *out_buf) { static const ssize_t buf_size = 0x2000; buf_resize(out_buf, buf_size); ssize_t actual_buf_len = 0; - bool first_read = true; - for (;;) { size_t amt_read = fread(buf_ptr(out_buf) + actual_buf_len, 1, buf_size, f); actual_buf_len += amt_read; - if (skip_shebang && first_read && buf_starts_with_str(out_buf, "#!")) { - size_t i = 0; - while (true) { - if (i > buf_len(out_buf)) { - zig_panic("shebang line exceeded %zd characters", buf_size); - } - - size_t current_pos = i; - i += 1; - - if (out_buf->list.at(current_pos) == '\n') { - break; - } - } - - ZigList *list = &out_buf->list; - memmove(list->items, list->items + i, list->length - i); - list->length -= i; - - actual_buf_len -= i; - } - if (amt_read != buf_size) { if (feof(f)) { buf_resize(out_buf, actual_buf_len); @@ -794,7 +770,6 @@ Error os_fetch_file(FILE *f, Buf *out_buf, bool skip_shebang) { } buf_resize(out_buf, actual_buf_len + buf_size); - first_read = false; } zig_unreachable(); } @@ -864,8 +839,8 @@ static Error os_exec_process_posix(const char *exe, ZigList &args, FILE *stdout_f = fdopen(stdout_pipe[0], "rb"); FILE *stderr_f = fdopen(stderr_pipe[0], "rb"); - Error err1 = os_fetch_file(stdout_f, out_stdout, false); - Error err2 = os_fetch_file(stderr_f, out_stderr, false); + Error err1 = os_fetch_file(stdout_f, out_stdout); + Error err2 = os_fetch_file(stderr_f, out_stderr); fclose(stdout_f); fclose(stderr_f); @@ -1097,7 +1072,7 @@ Error os_copy_file(Buf *src_path, Buf *dest_path) { } } -Error os_fetch_file_path(Buf *full_path, Buf *out_contents, bool skip_shebang) { +Error os_fetch_file_path(Buf *full_path, Buf *out_contents) { FILE *f = fopen(buf_ptr(full_path), "rb"); if (!f) { switch (errno) { @@ -1116,7 +1091,7 @@ Error os_fetch_file_path(Buf *full_path, Buf *out_contents, bool skip_shebang) { return ErrorFileSystem; } } - Error result = os_fetch_file(f, out_contents, skip_shebang); + Error result = os_fetch_file(f, out_contents); fclose(f); return result; } diff --git a/src/os.hpp b/src/os.hpp index b301937e83..058bb2020c 100644 --- a/src/os.hpp +++ b/src/os.hpp @@ -126,8 +126,8 @@ void os_file_close(OsFile *file); Error ATTRIBUTE_MUST_USE os_write_file(Buf *full_path, Buf *contents); Error ATTRIBUTE_MUST_USE os_copy_file(Buf *src_path, Buf *dest_path); -Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents, bool skip_shebang); -Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents, bool skip_shebang); +Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents); +Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents); Error ATTRIBUTE_MUST_USE os_get_cwd(Buf *out_cwd); diff --git a/std/zig/ast.zig b/std/zig/ast.zig index 9aba59f77c..7024f988a2 100644 --- a/std/zig/ast.zig +++ b/std/zig/ast.zig @@ -479,7 +479,6 @@ pub const Node = struct { doc_comments: ?*DocComment, decls: DeclList, eof_token: TokenIndex, - shebang: ?TokenIndex, pub const DeclList = SegmentedList(*Node, 4); @@ -491,7 +490,6 @@ pub const Node = struct { } pub fn firstToken(self: *const Root) TokenIndex { - if (self.shebang) |shebang| return shebang; return if (self.decls.len == 0) self.eof_token else (self.decls.at(0).*).firstToken(); } @@ -2235,7 +2233,6 @@ test "iterate" { .doc_comments = null, .decls = Node.Root.DeclList.init(std.debug.global_allocator), .eof_token = 0, - .shebang = null, }; var base = &root.base; testing.expect(base.iterate(0) == null); diff --git a/std/zig/parse.zig b/std/zig/parse.zig index 42fa6d8590..a461e15721 100644 --- a/std/zig/parse.zig +++ b/std/zig/parse.zig @@ -22,7 +22,6 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { .base = ast.Node{ .id = ast.Node.Id.Root }, .decls = ast.Node.Root.DeclList.init(arena), .doc_comments = null, - .shebang = null, // initialized when we get the eof token .eof_token = undefined, }; @@ -43,15 +42,6 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree { } var tok_it = tree.tokens.iterator(0); - // skip over shebang line - shebang: { - const shebang_tok_index = tok_it.index; - const shebang_tok_ptr = tok_it.peek() orelse break :shebang; - if (shebang_tok_ptr.id != Token.Id.ShebangLine) break :shebang; - root_node.shebang = shebang_tok_index; - _ = tok_it.next(); - } - // skip over line comments at the top of the file while (true) { const next_tok = tok_it.peek() orelse break; diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 82607dbbe9..111f0cd6ac 100644 --- a/std/zig/parser_test.zig +++ b/std/zig/parser_test.zig @@ -50,14 +50,6 @@ test "zig fmt: linksection" { ); } -test "zig fmt: shebang line" { - try testCanonical( - \\#!/usr/bin/env zig - \\pub fn main() void {} - \\ - ); -} - test "zig fmt: correctly move doc comments on struct fields" { try testTransform( \\pub const section_64 = extern struct { diff --git a/std/zig/render.zig b/std/zig/render.zig index f1fe23c2a8..74c1e2acfc 100644 --- a/std/zig/render.zig +++ b/std/zig/render.zig @@ -73,11 +73,6 @@ fn renderRoot( ) (@typeOf(stream).Child.Error || Error)!void { var tok_it = tree.tokens.iterator(0); - // render the shebang line - if (tree.root_node.shebang) |shebang| { - try stream.write(tree.tokenSlice(shebang)); - } - // render all the line comments at the beginning of the file while (tok_it.next()) |token| { if (token.id != Token.Id.LineComment) break; -- cgit v1.2.3 From 976080462cf62f6f112d38176b99e5bb8a57bf37 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 21 Apr 2019 17:24:58 -0400 Subject: translate-c: a little closer to self-hosted implementation --- CMakeLists.txt | 1 + src-self-hosted/clang.zig | 944 ++++++++++++++++++++++++++++++++++++++++ src-self-hosted/stage1.zig | 95 +++- src-self-hosted/translate_c.zig | 11 +- src/analyze.cpp | 2 +- src/analyze.hpp | 2 + src/ast_render.cpp | 4 +- src/ast_render.hpp | 2 +- src/codegen.cpp | 271 +++++++----- src/codegen.hpp | 3 +- src/error.cpp | 4 + src/error.hpp | 44 +- src/ir.cpp | 22 +- src/main.cpp | 3 +- src/translate_c.cpp | 94 +--- src/translate_c.hpp | 4 +- src/userland.cpp | 10 +- src/userland.h | 72 ++- src/zig_clang.h | 167 +++---- std/c.zig | 4 + std/io.zig | 30 +- std/io/c_out_stream.zig | 44 ++ 22 files changed, 1467 insertions(+), 366 deletions(-) create mode 100644 src-self-hosted/clang.zig create mode 100644 std/io/c_out_stream.zig (limited to 'src/codegen.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f8ae390ab..f3911699f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -508,6 +508,7 @@ set(ZIG_STD_FILES "heap.zig" "io.zig" "io/seekable_stream.zig" + "io/c_out_stream.zig" "json.zig" "lazy_init.zig" "linked_list.zig" diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig new file mode 100644 index 0000000000..6f7c7eb853 --- /dev/null +++ b/src-self-hosted/clang.zig @@ -0,0 +1,944 @@ +pub const struct_ZigClangAPValue = @OpaqueType(); +pub const struct_ZigClangAPSInt = @OpaqueType(); +pub const struct_ZigClangASTContext = @OpaqueType(); +pub const struct_ZigClangASTUnit = @OpaqueType(); +pub const struct_ZigClangArraySubscriptExpr = @OpaqueType(); +pub const struct_ZigClangArrayType = @OpaqueType(); +pub const struct_ZigClangAttributedType = @OpaqueType(); +pub const struct_ZigClangBinaryOperator = @OpaqueType(); +pub const struct_ZigClangBreakStmt = @OpaqueType(); +pub const struct_ZigClangBuiltinType = @OpaqueType(); +pub const struct_ZigClangCStyleCastExpr = @OpaqueType(); +pub const struct_ZigClangCallExpr = @OpaqueType(); +pub const struct_ZigClangCaseStmt = @OpaqueType(); +pub const struct_ZigClangCompoundAssignOperator = @OpaqueType(); +pub const struct_ZigClangCompoundStmt = @OpaqueType(); +pub const struct_ZigClangConditionalOperator = @OpaqueType(); +pub const struct_ZigClangConstantArrayType = @OpaqueType(); +pub const struct_ZigClangContinueStmt = @OpaqueType(); +pub const struct_ZigClangDecayedType = @OpaqueType(); +pub const struct_ZigClangDecl = @OpaqueType(); +pub const struct_ZigClangDeclRefExpr = @OpaqueType(); +pub const struct_ZigClangDeclStmt = @OpaqueType(); +pub const struct_ZigClangDefaultStmt = @OpaqueType(); +pub const struct_ZigClangDiagnosticOptions = @OpaqueType(); +pub const struct_ZigClangDiagnosticsEngine = @OpaqueType(); +pub const struct_ZigClangDoStmt = @OpaqueType(); +pub const struct_ZigClangElaboratedType = @OpaqueType(); +pub const struct_ZigClangEnumConstantDecl = @OpaqueType(); +pub const struct_ZigClangEnumDecl = @OpaqueType(); +pub const struct_ZigClangEnumType = @OpaqueType(); +pub const struct_ZigClangExpr = @OpaqueType(); +pub const struct_ZigClangFieldDecl = @OpaqueType(); +pub const struct_ZigClangFileID = @OpaqueType(); +pub const struct_ZigClangForStmt = @OpaqueType(); +pub const struct_ZigClangFullSourceLoc = @OpaqueType(); +pub const struct_ZigClangFunctionDecl = @OpaqueType(); +pub const struct_ZigClangFunctionProtoType = @OpaqueType(); +pub const struct_ZigClangIfStmt = @OpaqueType(); +pub const struct_ZigClangImplicitCastExpr = @OpaqueType(); +pub const struct_ZigClangIncompleteArrayType = @OpaqueType(); +pub const struct_ZigClangIntegerLiteral = @OpaqueType(); +pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType(); +pub const struct_ZigClangMemberExpr = @OpaqueType(); +pub const struct_ZigClangNamedDecl = @OpaqueType(); +pub const struct_ZigClangNone = @OpaqueType(); +pub const struct_ZigClangPCHContainerOperations = @OpaqueType(); +pub const struct_ZigClangParenExpr = @OpaqueType(); +pub const struct_ZigClangParenType = @OpaqueType(); +pub const struct_ZigClangParmVarDecl = @OpaqueType(); +pub const struct_ZigClangPointerType = @OpaqueType(); +pub const struct_ZigClangPreprocessedEntity = @OpaqueType(); +pub const struct_ZigClangRecordDecl = @OpaqueType(); +pub const struct_ZigClangRecordType = @OpaqueType(); +pub const struct_ZigClangReturnStmt = @OpaqueType(); +pub const struct_ZigClangSkipFunctionBodiesScope = @OpaqueType(); +pub const struct_ZigClangSourceManager = @OpaqueType(); +pub const struct_ZigClangSourceRange = @OpaqueType(); +pub const struct_ZigClangStmt = @OpaqueType(); +pub const struct_ZigClangStorageClass = @OpaqueType(); +pub const struct_ZigClangStringLiteral = @OpaqueType(); +pub const struct_ZigClangStringRef = @OpaqueType(); +pub const struct_ZigClangSwitchStmt = @OpaqueType(); +pub const struct_ZigClangTagDecl = @OpaqueType(); +pub const struct_ZigClangType = @OpaqueType(); +pub const struct_ZigClangTypedefNameDecl = @OpaqueType(); +pub const struct_ZigClangTypedefType = @OpaqueType(); +pub const struct_ZigClangUnaryExprOrTypeTraitExpr = @OpaqueType(); +pub const struct_ZigClangUnaryOperator = @OpaqueType(); +pub const struct_ZigClangValueDecl = @OpaqueType(); +pub const struct_ZigClangVarDecl = @OpaqueType(); +pub const struct_ZigClangWhileStmt = @OpaqueType(); +pub const ZigClangBO_PtrMemD = enum_ZigClangBO._PtrMemD; +pub const ZigClangBO_PtrMemI = enum_ZigClangBO._PtrMemI; +pub const ZigClangBO_Mul = enum_ZigClangBO._Mul; +pub const ZigClangBO_Div = enum_ZigClangBO._Div; +pub const ZigClangBO_Rem = enum_ZigClangBO._Rem; +pub const ZigClangBO_Add = enum_ZigClangBO._Add; +pub const ZigClangBO_Sub = enum_ZigClangBO._Sub; +pub const ZigClangBO_Shl = enum_ZigClangBO._Shl; +pub const ZigClangBO_Shr = enum_ZigClangBO._Shr; +pub const ZigClangBO_Cmp = enum_ZigClangBO._Cmp; +pub const ZigClangBO_LT = enum_ZigClangBO._LT; +pub const ZigClangBO_GT = enum_ZigClangBO._GT; +pub const ZigClangBO_LE = enum_ZigClangBO._LE; +pub const ZigClangBO_GE = enum_ZigClangBO._GE; +pub const ZigClangBO_EQ = enum_ZigClangBO._EQ; +pub const ZigClangBO_NE = enum_ZigClangBO._NE; +pub const ZigClangBO_And = enum_ZigClangBO._And; +pub const ZigClangBO_Xor = enum_ZigClangBO._Xor; +pub const ZigClangBO_Or = enum_ZigClangBO._Or; +pub const ZigClangBO_LAnd = enum_ZigClangBO._LAnd; +pub const ZigClangBO_LOr = enum_ZigClangBO._LOr; +pub const ZigClangBO_Assign = enum_ZigClangBO._Assign; +pub const ZigClangBO_MulAssign = enum_ZigClangBO._MulAssign; +pub const ZigClangBO_DivAssign = enum_ZigClangBO._DivAssign; +pub const ZigClangBO_RemAssign = enum_ZigClangBO._RemAssign; +pub const ZigClangBO_AddAssign = enum_ZigClangBO._AddAssign; +pub const ZigClangBO_SubAssign = enum_ZigClangBO._SubAssign; +pub const ZigClangBO_ShlAssign = enum_ZigClangBO._ShlAssign; +pub const ZigClangBO_ShrAssign = enum_ZigClangBO._ShrAssign; +pub const ZigClangBO_AndAssign = enum_ZigClangBO._AndAssign; +pub const ZigClangBO_XorAssign = enum_ZigClangBO._XorAssign; +pub const ZigClangBO_OrAssign = enum_ZigClangBO._OrAssign; +pub const ZigClangBO_Comma = enum_ZigClangBO._Comma; +pub const enum_ZigClangBO = extern enum { + _PtrMemD, + _PtrMemI, + _Mul, + _Div, + _Rem, + _Add, + _Sub, + _Shl, + _Shr, + _Cmp, + _LT, + _GT, + _LE, + _GE, + _EQ, + _NE, + _And, + _Xor, + _Or, + _LAnd, + _LOr, + _Assign, + _MulAssign, + _DivAssign, + _RemAssign, + _AddAssign, + _SubAssign, + _ShlAssign, + _ShrAssign, + _AndAssign, + _XorAssign, + _OrAssign, + _Comma, +}; +pub const ZigClangUO_PostInc = enum_ZigClangUO._PostInc; +pub const ZigClangUO_PostDec = enum_ZigClangUO._PostDec; +pub const ZigClangUO_PreInc = enum_ZigClangUO._PreInc; +pub const ZigClangUO_PreDec = enum_ZigClangUO._PreDec; +pub const ZigClangUO_AddrOf = enum_ZigClangUO._AddrOf; +pub const ZigClangUO_Deref = enum_ZigClangUO._Deref; +pub const ZigClangUO_Plus = enum_ZigClangUO._Plus; +pub const ZigClangUO_Minus = enum_ZigClangUO._Minus; +pub const ZigClangUO_Not = enum_ZigClangUO._Not; +pub const ZigClangUO_LNot = enum_ZigClangUO._LNot; +pub const ZigClangUO_Real = enum_ZigClangUO._Real; +pub const ZigClangUO_Imag = enum_ZigClangUO._Imag; +pub const ZigClangUO_Extension = enum_ZigClangUO._Extension; +pub const ZigClangUO_Coawait = enum_ZigClangUO._Coawait; +pub const enum_ZigClangUO = extern enum { + _PostInc, + _PostDec, + _PreInc, + _PreDec, + _AddrOf, + _Deref, + _Plus, + _Minus, + _Not, + _LNot, + _Real, + _Imag, + _Extension, + _Coawait, +}; +pub const ZigClangType_Builtin = enum_ZigClangTypeClass.ZigClangType_Builtin; +pub const ZigClangType_Complex = enum_ZigClangTypeClass.ZigClangType_Complex; +pub const ZigClangType_Pointer = enum_ZigClangTypeClass.ZigClangType_Pointer; +pub const ZigClangType_BlockPointer = enum_ZigClangTypeClass.ZigClangType_BlockPointer; +pub const ZigClangType_LValueReference = enum_ZigClangTypeClass.ZigClangType_LValueReference; +pub const ZigClangType_RValueReference = enum_ZigClangTypeClass.ZigClangType_RValueReference; +pub const ZigClangType_MemberPointer = enum_ZigClangTypeClass.ZigClangType_MemberPointer; +pub const ZigClangType_ConstantArray = enum_ZigClangTypeClass.ZigClangType_ConstantArray; +pub const ZigClangType_IncompleteArray = enum_ZigClangTypeClass.ZigClangType_IncompleteArray; +pub const ZigClangType_VariableArray = enum_ZigClangTypeClass.ZigClangType_VariableArray; +pub const ZigClangType_DependentSizedArray = enum_ZigClangTypeClass.ZigClangType_DependentSizedArray; +pub const ZigClangType_DependentSizedExtVector = enum_ZigClangTypeClass.ZigClangType_DependentSizedExtVector; +pub const ZigClangType_DependentAddressSpace = enum_ZigClangTypeClass.ZigClangType_DependentAddressSpace; +pub const ZigClangType_Vector = enum_ZigClangTypeClass.ZigClangType_Vector; +pub const ZigClangType_DependentVector = enum_ZigClangTypeClass.ZigClangType_DependentVector; +pub const ZigClangType_ExtVector = enum_ZigClangTypeClass.ZigClangType_ExtVector; +pub const ZigClangType_FunctionProto = enum_ZigClangTypeClass.ZigClangType_FunctionProto; +pub const ZigClangType_FunctionNoProto = enum_ZigClangTypeClass.ZigClangType_FunctionNoProto; +pub const ZigClangType_UnresolvedUsing = enum_ZigClangTypeClass.ZigClangType_UnresolvedUsing; +pub const ZigClangType_Paren = enum_ZigClangTypeClass.ZigClangType_Paren; +pub const ZigClangType_Typedef = enum_ZigClangTypeClass.ZigClangType_Typedef; +pub const ZigClangType_Adjusted = enum_ZigClangTypeClass.ZigClangType_Adjusted; +pub const ZigClangType_Decayed = enum_ZigClangTypeClass.ZigClangType_Decayed; +pub const ZigClangType_TypeOfExpr = enum_ZigClangTypeClass.ZigClangType_TypeOfExpr; +pub const ZigClangType_TypeOf = enum_ZigClangTypeClass.ZigClangType_TypeOf; +pub const ZigClangType_Decltype = enum_ZigClangTypeClass.ZigClangType_Decltype; +pub const ZigClangType_UnaryTransform = enum_ZigClangTypeClass.ZigClangType_UnaryTransform; +pub const ZigClangType_Record = enum_ZigClangTypeClass.ZigClangType_Record; +pub const ZigClangType_Enum = enum_ZigClangTypeClass.ZigClangType_Enum; +pub const ZigClangType_Elaborated = enum_ZigClangTypeClass.ZigClangType_Elaborated; +pub const ZigClangType_Attributed = enum_ZigClangTypeClass.ZigClangType_Attributed; +pub const ZigClangType_TemplateTypeParm = enum_ZigClangTypeClass.ZigClangType_TemplateTypeParm; +pub const ZigClangType_SubstTemplateTypeParm = enum_ZigClangTypeClass.ZigClangType_SubstTemplateTypeParm; +pub const ZigClangType_SubstTemplateTypeParmPack = enum_ZigClangTypeClass.ZigClangType_SubstTemplateTypeParmPack; +pub const ZigClangType_TemplateSpecialization = enum_ZigClangTypeClass.ZigClangType_TemplateSpecialization; +pub const ZigClangType_Auto = enum_ZigClangTypeClass.ZigClangType_Auto; +pub const ZigClangType_DeducedTemplateSpecialization = enum_ZigClangTypeClass.ZigClangType_DeducedTemplateSpecialization; +pub const ZigClangType_InjectedClassName = enum_ZigClangTypeClass.ZigClangType_InjectedClassName; +pub const ZigClangType_DependentName = enum_ZigClangTypeClass.ZigClangType_DependentName; +pub const ZigClangType_DependentTemplateSpecialization = enum_ZigClangTypeClass.ZigClangType_DependentTemplateSpecialization; +pub const ZigClangType_PackExpansion = enum_ZigClangTypeClass.ZigClangType_PackExpansion; +pub const ZigClangType_ObjCTypeParam = enum_ZigClangTypeClass.ZigClangType_ObjCTypeParam; +pub const ZigClangType_ObjCObject = enum_ZigClangTypeClass.ZigClangType_ObjCObject; +pub const ZigClangType_ObjCInterface = enum_ZigClangTypeClass.ZigClangType_ObjCInterface; +pub const ZigClangType_ObjCObjectPointer = enum_ZigClangTypeClass.ZigClangType_ObjCObjectPointer; +pub const ZigClangType_Pipe = enum_ZigClangTypeClass.ZigClangType_Pipe; +pub const ZigClangType_Atomic = enum_ZigClangTypeClass.ZigClangType_Atomic; +pub const enum_ZigClangTypeClass = extern enum { + ZigClangType_Builtin, + ZigClangType_Complex, + ZigClangType_Pointer, + ZigClangType_BlockPointer, + ZigClangType_LValueReference, + ZigClangType_RValueReference, + ZigClangType_MemberPointer, + ZigClangType_ConstantArray, + ZigClangType_IncompleteArray, + ZigClangType_VariableArray, + ZigClangType_DependentSizedArray, + ZigClangType_DependentSizedExtVector, + ZigClangType_DependentAddressSpace, + ZigClangType_Vector, + ZigClangType_DependentVector, + ZigClangType_ExtVector, + ZigClangType_FunctionProto, + ZigClangType_FunctionNoProto, + ZigClangType_UnresolvedUsing, + ZigClangType_Paren, + ZigClangType_Typedef, + ZigClangType_Adjusted, + ZigClangType_Decayed, + ZigClangType_TypeOfExpr, + ZigClangType_TypeOf, + ZigClangType_Decltype, + ZigClangType_UnaryTransform, + ZigClangType_Record, + ZigClangType_Enum, + ZigClangType_Elaborated, + ZigClangType_Attributed, + ZigClangType_TemplateTypeParm, + ZigClangType_SubstTemplateTypeParm, + ZigClangType_SubstTemplateTypeParmPack, + ZigClangType_TemplateSpecialization, + ZigClangType_Auto, + ZigClangType_DeducedTemplateSpecialization, + ZigClangType_InjectedClassName, + ZigClangType_DependentName, + ZigClangType_DependentTemplateSpecialization, + ZigClangType_PackExpansion, + ZigClangType_ObjCTypeParam, + ZigClangType_ObjCObject, + ZigClangType_ObjCInterface, + ZigClangType_ObjCObjectPointer, + ZigClangType_Pipe, + ZigClangType_Atomic, +}; +pub const ZigClangStmt_NoStmtClass = enum_ZigClangStmtClass.ZigClangStmt_NoStmtClass; +pub const ZigClangStmt_GCCAsmStmtClass = enum_ZigClangStmtClass.ZigClangStmt_GCCAsmStmtClass; +pub const ZigClangStmt_MSAsmStmtClass = enum_ZigClangStmtClass.ZigClangStmt_MSAsmStmtClass; +pub const ZigClangStmt_AttributedStmtClass = enum_ZigClangStmtClass.ZigClangStmt_AttributedStmtClass; +pub const ZigClangStmt_BreakStmtClass = enum_ZigClangStmtClass.ZigClangStmt_BreakStmtClass; +pub const ZigClangStmt_CXXCatchStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CXXCatchStmtClass; +pub const ZigClangStmt_CXXForRangeStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CXXForRangeStmtClass; +pub const ZigClangStmt_CXXTryStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CXXTryStmtClass; +pub const ZigClangStmt_CapturedStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CapturedStmtClass; +pub const ZigClangStmt_CompoundStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CompoundStmtClass; +pub const ZigClangStmt_ContinueStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ContinueStmtClass; +pub const ZigClangStmt_CoreturnStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CoreturnStmtClass; +pub const ZigClangStmt_CoroutineBodyStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CoroutineBodyStmtClass; +pub const ZigClangStmt_DeclStmtClass = enum_ZigClangStmtClass.ZigClangStmt_DeclStmtClass; +pub const ZigClangStmt_DoStmtClass = enum_ZigClangStmtClass.ZigClangStmt_DoStmtClass; +pub const ZigClangStmt_BinaryConditionalOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_BinaryConditionalOperatorClass; +pub const ZigClangStmt_ConditionalOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_ConditionalOperatorClass; +pub const ZigClangStmt_AddrLabelExprClass = enum_ZigClangStmtClass.ZigClangStmt_AddrLabelExprClass; +pub const ZigClangStmt_ArrayInitIndexExprClass = enum_ZigClangStmtClass.ZigClangStmt_ArrayInitIndexExprClass; +pub const ZigClangStmt_ArrayInitLoopExprClass = enum_ZigClangStmtClass.ZigClangStmt_ArrayInitLoopExprClass; +pub const ZigClangStmt_ArraySubscriptExprClass = enum_ZigClangStmtClass.ZigClangStmt_ArraySubscriptExprClass; +pub const ZigClangStmt_ArrayTypeTraitExprClass = enum_ZigClangStmtClass.ZigClangStmt_ArrayTypeTraitExprClass; +pub const ZigClangStmt_AsTypeExprClass = enum_ZigClangStmtClass.ZigClangStmt_AsTypeExprClass; +pub const ZigClangStmt_AtomicExprClass = enum_ZigClangStmtClass.ZigClangStmt_AtomicExprClass; +pub const ZigClangStmt_BinaryOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_BinaryOperatorClass; +pub const ZigClangStmt_CompoundAssignOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_CompoundAssignOperatorClass; +pub const ZigClangStmt_BlockExprClass = enum_ZigClangStmtClass.ZigClangStmt_BlockExprClass; +pub const ZigClangStmt_CXXBindTemporaryExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXBindTemporaryExprClass; +pub const ZigClangStmt_CXXBoolLiteralExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXBoolLiteralExprClass; +pub const ZigClangStmt_CXXConstructExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXConstructExprClass; +pub const ZigClangStmt_CXXTemporaryObjectExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXTemporaryObjectExprClass; +pub const ZigClangStmt_CXXDefaultArgExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDefaultArgExprClass; +pub const ZigClangStmt_CXXDefaultInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDefaultInitExprClass; +pub const ZigClangStmt_CXXDeleteExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDeleteExprClass; +pub const ZigClangStmt_CXXDependentScopeMemberExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDependentScopeMemberExprClass; +pub const ZigClangStmt_CXXFoldExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXFoldExprClass; +pub const ZigClangStmt_CXXInheritedCtorInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXInheritedCtorInitExprClass; +pub const ZigClangStmt_CXXNewExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXNewExprClass; +pub const ZigClangStmt_CXXNoexceptExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXNoexceptExprClass; +pub const ZigClangStmt_CXXNullPtrLiteralExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXNullPtrLiteralExprClass; +pub const ZigClangStmt_CXXPseudoDestructorExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXPseudoDestructorExprClass; +pub const ZigClangStmt_CXXScalarValueInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXScalarValueInitExprClass; +pub const ZigClangStmt_CXXStdInitializerListExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXStdInitializerListExprClass; +pub const ZigClangStmt_CXXThisExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXThisExprClass; +pub const ZigClangStmt_CXXThrowExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXThrowExprClass; +pub const ZigClangStmt_CXXTypeidExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXTypeidExprClass; +pub const ZigClangStmt_CXXUnresolvedConstructExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXUnresolvedConstructExprClass; +pub const ZigClangStmt_CXXUuidofExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXUuidofExprClass; +pub const ZigClangStmt_CallExprClass = enum_ZigClangStmtClass.ZigClangStmt_CallExprClass; +pub const ZigClangStmt_CUDAKernelCallExprClass = enum_ZigClangStmtClass.ZigClangStmt_CUDAKernelCallExprClass; +pub const ZigClangStmt_CXXMemberCallExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXMemberCallExprClass; +pub const ZigClangStmt_CXXOperatorCallExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXOperatorCallExprClass; +pub const ZigClangStmt_UserDefinedLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_UserDefinedLiteralClass; +pub const ZigClangStmt_CStyleCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CStyleCastExprClass; +pub const ZigClangStmt_CXXFunctionalCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXFunctionalCastExprClass; +pub const ZigClangStmt_CXXConstCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXConstCastExprClass; +pub const ZigClangStmt_CXXDynamicCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDynamicCastExprClass; +pub const ZigClangStmt_CXXReinterpretCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXReinterpretCastExprClass; +pub const ZigClangStmt_CXXStaticCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXStaticCastExprClass; +pub const ZigClangStmt_ObjCBridgedCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCBridgedCastExprClass; +pub const ZigClangStmt_ImplicitCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_ImplicitCastExprClass; +pub const ZigClangStmt_CharacterLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_CharacterLiteralClass; +pub const ZigClangStmt_ChooseExprClass = enum_ZigClangStmtClass.ZigClangStmt_ChooseExprClass; +pub const ZigClangStmt_CompoundLiteralExprClass = enum_ZigClangStmtClass.ZigClangStmt_CompoundLiteralExprClass; +pub const ZigClangStmt_ConvertVectorExprClass = enum_ZigClangStmtClass.ZigClangStmt_ConvertVectorExprClass; +pub const ZigClangStmt_CoawaitExprClass = enum_ZigClangStmtClass.ZigClangStmt_CoawaitExprClass; +pub const ZigClangStmt_CoyieldExprClass = enum_ZigClangStmtClass.ZigClangStmt_CoyieldExprClass; +pub const ZigClangStmt_DeclRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_DeclRefExprClass; +pub const ZigClangStmt_DependentCoawaitExprClass = enum_ZigClangStmtClass.ZigClangStmt_DependentCoawaitExprClass; +pub const ZigClangStmt_DependentScopeDeclRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_DependentScopeDeclRefExprClass; +pub const ZigClangStmt_DesignatedInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_DesignatedInitExprClass; +pub const ZigClangStmt_DesignatedInitUpdateExprClass = enum_ZigClangStmtClass.ZigClangStmt_DesignatedInitUpdateExprClass; +pub const ZigClangStmt_ExpressionTraitExprClass = enum_ZigClangStmtClass.ZigClangStmt_ExpressionTraitExprClass; +pub const ZigClangStmt_ExtVectorElementExprClass = enum_ZigClangStmtClass.ZigClangStmt_ExtVectorElementExprClass; +pub const ZigClangStmt_FixedPointLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_FixedPointLiteralClass; +pub const ZigClangStmt_FloatingLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_FloatingLiteralClass; +pub const ZigClangStmt_ConstantExprClass = enum_ZigClangStmtClass.ZigClangStmt_ConstantExprClass; +pub const ZigClangStmt_ExprWithCleanupsClass = enum_ZigClangStmtClass.ZigClangStmt_ExprWithCleanupsClass; +pub const ZigClangStmt_FunctionParmPackExprClass = enum_ZigClangStmtClass.ZigClangStmt_FunctionParmPackExprClass; +pub const ZigClangStmt_GNUNullExprClass = enum_ZigClangStmtClass.ZigClangStmt_GNUNullExprClass; +pub const ZigClangStmt_GenericSelectionExprClass = enum_ZigClangStmtClass.ZigClangStmt_GenericSelectionExprClass; +pub const ZigClangStmt_ImaginaryLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_ImaginaryLiteralClass; +pub const ZigClangStmt_ImplicitValueInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_ImplicitValueInitExprClass; +pub const ZigClangStmt_InitListExprClass = enum_ZigClangStmtClass.ZigClangStmt_InitListExprClass; +pub const ZigClangStmt_IntegerLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_IntegerLiteralClass; +pub const ZigClangStmt_LambdaExprClass = enum_ZigClangStmtClass.ZigClangStmt_LambdaExprClass; +pub const ZigClangStmt_MSPropertyRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_MSPropertyRefExprClass; +pub const ZigClangStmt_MSPropertySubscriptExprClass = enum_ZigClangStmtClass.ZigClangStmt_MSPropertySubscriptExprClass; +pub const ZigClangStmt_MaterializeTemporaryExprClass = enum_ZigClangStmtClass.ZigClangStmt_MaterializeTemporaryExprClass; +pub const ZigClangStmt_MemberExprClass = enum_ZigClangStmtClass.ZigClangStmt_MemberExprClass; +pub const ZigClangStmt_NoInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_NoInitExprClass; +pub const ZigClangStmt_OMPArraySectionExprClass = enum_ZigClangStmtClass.ZigClangStmt_OMPArraySectionExprClass; +pub const ZigClangStmt_ObjCArrayLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCArrayLiteralClass; +pub const ZigClangStmt_ObjCAvailabilityCheckExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAvailabilityCheckExprClass; +pub const ZigClangStmt_ObjCBoolLiteralExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCBoolLiteralExprClass; +pub const ZigClangStmt_ObjCBoxedExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCBoxedExprClass; +pub const ZigClangStmt_ObjCDictionaryLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCDictionaryLiteralClass; +pub const ZigClangStmt_ObjCEncodeExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCEncodeExprClass; +pub const ZigClangStmt_ObjCIndirectCopyRestoreExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCIndirectCopyRestoreExprClass; +pub const ZigClangStmt_ObjCIsaExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCIsaExprClass; +pub const ZigClangStmt_ObjCIvarRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCIvarRefExprClass; +pub const ZigClangStmt_ObjCMessageExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCMessageExprClass; +pub const ZigClangStmt_ObjCPropertyRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCPropertyRefExprClass; +pub const ZigClangStmt_ObjCProtocolExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCProtocolExprClass; +pub const ZigClangStmt_ObjCSelectorExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCSelectorExprClass; +pub const ZigClangStmt_ObjCStringLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCStringLiteralClass; +pub const ZigClangStmt_ObjCSubscriptRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCSubscriptRefExprClass; +pub const ZigClangStmt_OffsetOfExprClass = enum_ZigClangStmtClass.ZigClangStmt_OffsetOfExprClass; +pub const ZigClangStmt_OpaqueValueExprClass = enum_ZigClangStmtClass.ZigClangStmt_OpaqueValueExprClass; +pub const ZigClangStmt_UnresolvedLookupExprClass = enum_ZigClangStmtClass.ZigClangStmt_UnresolvedLookupExprClass; +pub const ZigClangStmt_UnresolvedMemberExprClass = enum_ZigClangStmtClass.ZigClangStmt_UnresolvedMemberExprClass; +pub const ZigClangStmt_PackExpansionExprClass = enum_ZigClangStmtClass.ZigClangStmt_PackExpansionExprClass; +pub const ZigClangStmt_ParenExprClass = enum_ZigClangStmtClass.ZigClangStmt_ParenExprClass; +pub const ZigClangStmt_ParenListExprClass = enum_ZigClangStmtClass.ZigClangStmt_ParenListExprClass; +pub const ZigClangStmt_PredefinedExprClass = enum_ZigClangStmtClass.ZigClangStmt_PredefinedExprClass; +pub const ZigClangStmt_PseudoObjectExprClass = enum_ZigClangStmtClass.ZigClangStmt_PseudoObjectExprClass; +pub const ZigClangStmt_ShuffleVectorExprClass = enum_ZigClangStmtClass.ZigClangStmt_ShuffleVectorExprClass; +pub const ZigClangStmt_SizeOfPackExprClass = enum_ZigClangStmtClass.ZigClangStmt_SizeOfPackExprClass; +pub const ZigClangStmt_StmtExprClass = enum_ZigClangStmtClass.ZigClangStmt_StmtExprClass; +pub const ZigClangStmt_StringLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_StringLiteralClass; +pub const ZigClangStmt_SubstNonTypeTemplateParmExprClass = enum_ZigClangStmtClass.ZigClangStmt_SubstNonTypeTemplateParmExprClass; +pub const ZigClangStmt_SubstNonTypeTemplateParmPackExprClass = enum_ZigClangStmtClass.ZigClangStmt_SubstNonTypeTemplateParmPackExprClass; +pub const ZigClangStmt_TypeTraitExprClass = enum_ZigClangStmtClass.ZigClangStmt_TypeTraitExprClass; +pub const ZigClangStmt_TypoExprClass = enum_ZigClangStmtClass.ZigClangStmt_TypoExprClass; +pub const ZigClangStmt_UnaryExprOrTypeTraitExprClass = enum_ZigClangStmtClass.ZigClangStmt_UnaryExprOrTypeTraitExprClass; +pub const ZigClangStmt_UnaryOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_UnaryOperatorClass; +pub const ZigClangStmt_VAArgExprClass = enum_ZigClangStmtClass.ZigClangStmt_VAArgExprClass; +pub const ZigClangStmt_ForStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ForStmtClass; +pub const ZigClangStmt_GotoStmtClass = enum_ZigClangStmtClass.ZigClangStmt_GotoStmtClass; +pub const ZigClangStmt_IfStmtClass = enum_ZigClangStmtClass.ZigClangStmt_IfStmtClass; +pub const ZigClangStmt_IndirectGotoStmtClass = enum_ZigClangStmtClass.ZigClangStmt_IndirectGotoStmtClass; +pub const ZigClangStmt_LabelStmtClass = enum_ZigClangStmtClass.ZigClangStmt_LabelStmtClass; +pub const ZigClangStmt_MSDependentExistsStmtClass = enum_ZigClangStmtClass.ZigClangStmt_MSDependentExistsStmtClass; +pub const ZigClangStmt_NullStmtClass = enum_ZigClangStmtClass.ZigClangStmt_NullStmtClass; +pub const ZigClangStmt_OMPAtomicDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPAtomicDirectiveClass; +pub const ZigClangStmt_OMPBarrierDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPBarrierDirectiveClass; +pub const ZigClangStmt_OMPCancelDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPCancelDirectiveClass; +pub const ZigClangStmt_OMPCancellationPointDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPCancellationPointDirectiveClass; +pub const ZigClangStmt_OMPCriticalDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPCriticalDirectiveClass; +pub const ZigClangStmt_OMPFlushDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPFlushDirectiveClass; +pub const ZigClangStmt_OMPDistributeDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPDistributeDirectiveClass; +pub const ZigClangStmt_OMPDistributeParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPDistributeParallelForDirectiveClass; +pub const ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass; +pub const ZigClangStmt_OMPDistributeSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPDistributeSimdDirectiveClass; +pub const ZigClangStmt_OMPForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPForDirectiveClass; +pub const ZigClangStmt_OMPForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPForSimdDirectiveClass; +pub const ZigClangStmt_OMPParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPParallelForDirectiveClass; +pub const ZigClangStmt_OMPParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPParallelForSimdDirectiveClass; +pub const ZigClangStmt_OMPSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPSimdDirectiveClass; +pub const ZigClangStmt_OMPTargetParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetParallelForSimdDirectiveClass; +pub const ZigClangStmt_OMPTargetSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetSimdDirectiveClass; +pub const ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass; +pub const ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass; +pub const ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass; +pub const ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass; +pub const ZigClangStmt_OMPTaskLoopDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskLoopDirectiveClass; +pub const ZigClangStmt_OMPTaskLoopSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskLoopSimdDirectiveClass; +pub const ZigClangStmt_OMPTeamsDistributeDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDistributeDirectiveClass; +pub const ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass; +pub const ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass; +pub const ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass; +pub const ZigClangStmt_OMPMasterDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPMasterDirectiveClass; +pub const ZigClangStmt_OMPOrderedDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPOrderedDirectiveClass; +pub const ZigClangStmt_OMPParallelDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPParallelDirectiveClass; +pub const ZigClangStmt_OMPParallelSectionsDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPParallelSectionsDirectiveClass; +pub const ZigClangStmt_OMPSectionDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPSectionDirectiveClass; +pub const ZigClangStmt_OMPSectionsDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPSectionsDirectiveClass; +pub const ZigClangStmt_OMPSingleDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPSingleDirectiveClass; +pub const ZigClangStmt_OMPTargetDataDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetDataDirectiveClass; +pub const ZigClangStmt_OMPTargetDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetDirectiveClass; +pub const ZigClangStmt_OMPTargetEnterDataDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetEnterDataDirectiveClass; +pub const ZigClangStmt_OMPTargetExitDataDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetExitDataDirectiveClass; +pub const ZigClangStmt_OMPTargetParallelDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetParallelDirectiveClass; +pub const ZigClangStmt_OMPTargetParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetParallelForDirectiveClass; +pub const ZigClangStmt_OMPTargetTeamsDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDirectiveClass; +pub const ZigClangStmt_OMPTargetUpdateDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetUpdateDirectiveClass; +pub const ZigClangStmt_OMPTaskDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskDirectiveClass; +pub const ZigClangStmt_OMPTaskgroupDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskgroupDirectiveClass; +pub const ZigClangStmt_OMPTaskwaitDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskwaitDirectiveClass; +pub const ZigClangStmt_OMPTaskyieldDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskyieldDirectiveClass; +pub const ZigClangStmt_OMPTeamsDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDirectiveClass; +pub const ZigClangStmt_ObjCAtCatchStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtCatchStmtClass; +pub const ZigClangStmt_ObjCAtFinallyStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtFinallyStmtClass; +pub const ZigClangStmt_ObjCAtSynchronizedStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtSynchronizedStmtClass; +pub const ZigClangStmt_ObjCAtThrowStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtThrowStmtClass; +pub const ZigClangStmt_ObjCAtTryStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtTryStmtClass; +pub const ZigClangStmt_ObjCAutoreleasePoolStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAutoreleasePoolStmtClass; +pub const ZigClangStmt_ObjCForCollectionStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCForCollectionStmtClass; +pub const ZigClangStmt_ReturnStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ReturnStmtClass; +pub const ZigClangStmt_SEHExceptStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SEHExceptStmtClass; +pub const ZigClangStmt_SEHFinallyStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SEHFinallyStmtClass; +pub const ZigClangStmt_SEHLeaveStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SEHLeaveStmtClass; +pub const ZigClangStmt_SEHTryStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SEHTryStmtClass; +pub const ZigClangStmt_CaseStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CaseStmtClass; +pub const ZigClangStmt_DefaultStmtClass = enum_ZigClangStmtClass.ZigClangStmt_DefaultStmtClass; +pub const ZigClangStmt_SwitchStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SwitchStmtClass; +pub const ZigClangStmt_WhileStmtClass = enum_ZigClangStmtClass.ZigClangStmt_WhileStmtClass; +pub const enum_ZigClangStmtClass = extern enum { + ZigClangStmt_NoStmtClass = 0, + ZigClangStmt_GCCAsmStmtClass = 1, + ZigClangStmt_MSAsmStmtClass = 2, + ZigClangStmt_AttributedStmtClass = 3, + ZigClangStmt_BreakStmtClass = 4, + ZigClangStmt_CXXCatchStmtClass = 5, + ZigClangStmt_CXXForRangeStmtClass = 6, + ZigClangStmt_CXXTryStmtClass = 7, + ZigClangStmt_CapturedStmtClass = 8, + ZigClangStmt_CompoundStmtClass = 9, + ZigClangStmt_ContinueStmtClass = 10, + ZigClangStmt_CoreturnStmtClass = 11, + ZigClangStmt_CoroutineBodyStmtClass = 12, + ZigClangStmt_DeclStmtClass = 13, + ZigClangStmt_DoStmtClass = 14, + ZigClangStmt_BinaryConditionalOperatorClass = 15, + ZigClangStmt_ConditionalOperatorClass = 16, + ZigClangStmt_AddrLabelExprClass = 17, + ZigClangStmt_ArrayInitIndexExprClass = 18, + ZigClangStmt_ArrayInitLoopExprClass = 19, + ZigClangStmt_ArraySubscriptExprClass = 20, + ZigClangStmt_ArrayTypeTraitExprClass = 21, + ZigClangStmt_AsTypeExprClass = 22, + ZigClangStmt_AtomicExprClass = 23, + ZigClangStmt_BinaryOperatorClass = 24, + ZigClangStmt_CompoundAssignOperatorClass = 25, + ZigClangStmt_BlockExprClass = 26, + ZigClangStmt_CXXBindTemporaryExprClass = 27, + ZigClangStmt_CXXBoolLiteralExprClass = 28, + ZigClangStmt_CXXConstructExprClass = 29, + ZigClangStmt_CXXTemporaryObjectExprClass = 30, + ZigClangStmt_CXXDefaultArgExprClass = 31, + ZigClangStmt_CXXDefaultInitExprClass = 32, + ZigClangStmt_CXXDeleteExprClass = 33, + ZigClangStmt_CXXDependentScopeMemberExprClass = 34, + ZigClangStmt_CXXFoldExprClass = 35, + ZigClangStmt_CXXInheritedCtorInitExprClass = 36, + ZigClangStmt_CXXNewExprClass = 37, + ZigClangStmt_CXXNoexceptExprClass = 38, + ZigClangStmt_CXXNullPtrLiteralExprClass = 39, + ZigClangStmt_CXXPseudoDestructorExprClass = 40, + ZigClangStmt_CXXScalarValueInitExprClass = 41, + ZigClangStmt_CXXStdInitializerListExprClass = 42, + ZigClangStmt_CXXThisExprClass = 43, + ZigClangStmt_CXXThrowExprClass = 44, + ZigClangStmt_CXXTypeidExprClass = 45, + ZigClangStmt_CXXUnresolvedConstructExprClass = 46, + ZigClangStmt_CXXUuidofExprClass = 47, + ZigClangStmt_CallExprClass = 48, + ZigClangStmt_CUDAKernelCallExprClass = 49, + ZigClangStmt_CXXMemberCallExprClass = 50, + ZigClangStmt_CXXOperatorCallExprClass = 51, + ZigClangStmt_UserDefinedLiteralClass = 52, + ZigClangStmt_CStyleCastExprClass = 53, + ZigClangStmt_CXXFunctionalCastExprClass = 54, + ZigClangStmt_CXXConstCastExprClass = 55, + ZigClangStmt_CXXDynamicCastExprClass = 56, + ZigClangStmt_CXXReinterpretCastExprClass = 57, + ZigClangStmt_CXXStaticCastExprClass = 58, + ZigClangStmt_ObjCBridgedCastExprClass = 59, + ZigClangStmt_ImplicitCastExprClass = 60, + ZigClangStmt_CharacterLiteralClass = 61, + ZigClangStmt_ChooseExprClass = 62, + ZigClangStmt_CompoundLiteralExprClass = 63, + ZigClangStmt_ConvertVectorExprClass = 64, + ZigClangStmt_CoawaitExprClass = 65, + ZigClangStmt_CoyieldExprClass = 66, + ZigClangStmt_DeclRefExprClass = 67, + ZigClangStmt_DependentCoawaitExprClass = 68, + ZigClangStmt_DependentScopeDeclRefExprClass = 69, + ZigClangStmt_DesignatedInitExprClass = 70, + ZigClangStmt_DesignatedInitUpdateExprClass = 71, + ZigClangStmt_ExpressionTraitExprClass = 72, + ZigClangStmt_ExtVectorElementExprClass = 73, + ZigClangStmt_FixedPointLiteralClass = 74, + ZigClangStmt_FloatingLiteralClass = 75, + ZigClangStmt_ConstantExprClass = 76, + ZigClangStmt_ExprWithCleanupsClass = 77, + ZigClangStmt_FunctionParmPackExprClass = 78, + ZigClangStmt_GNUNullExprClass = 79, + ZigClangStmt_GenericSelectionExprClass = 80, + ZigClangStmt_ImaginaryLiteralClass = 81, + ZigClangStmt_ImplicitValueInitExprClass = 82, + ZigClangStmt_InitListExprClass = 83, + ZigClangStmt_IntegerLiteralClass = 84, + ZigClangStmt_LambdaExprClass = 85, + ZigClangStmt_MSPropertyRefExprClass = 86, + ZigClangStmt_MSPropertySubscriptExprClass = 87, + ZigClangStmt_MaterializeTemporaryExprClass = 88, + ZigClangStmt_MemberExprClass = 89, + ZigClangStmt_NoInitExprClass = 90, + ZigClangStmt_OMPArraySectionExprClass = 91, + ZigClangStmt_ObjCArrayLiteralClass = 92, + ZigClangStmt_ObjCAvailabilityCheckExprClass = 93, + ZigClangStmt_ObjCBoolLiteralExprClass = 94, + ZigClangStmt_ObjCBoxedExprClass = 95, + ZigClangStmt_ObjCDictionaryLiteralClass = 96, + ZigClangStmt_ObjCEncodeExprClass = 97, + ZigClangStmt_ObjCIndirectCopyRestoreExprClass = 98, + ZigClangStmt_ObjCIsaExprClass = 99, + ZigClangStmt_ObjCIvarRefExprClass = 100, + ZigClangStmt_ObjCMessageExprClass = 101, + ZigClangStmt_ObjCPropertyRefExprClass = 102, + ZigClangStmt_ObjCProtocolExprClass = 103, + ZigClangStmt_ObjCSelectorExprClass = 104, + ZigClangStmt_ObjCStringLiteralClass = 105, + ZigClangStmt_ObjCSubscriptRefExprClass = 106, + ZigClangStmt_OffsetOfExprClass = 107, + ZigClangStmt_OpaqueValueExprClass = 108, + ZigClangStmt_UnresolvedLookupExprClass = 109, + ZigClangStmt_UnresolvedMemberExprClass = 110, + ZigClangStmt_PackExpansionExprClass = 111, + ZigClangStmt_ParenExprClass = 112, + ZigClangStmt_ParenListExprClass = 113, + ZigClangStmt_PredefinedExprClass = 114, + ZigClangStmt_PseudoObjectExprClass = 115, + ZigClangStmt_ShuffleVectorExprClass = 116, + ZigClangStmt_SizeOfPackExprClass = 117, + ZigClangStmt_StmtExprClass = 118, + ZigClangStmt_StringLiteralClass = 119, + ZigClangStmt_SubstNonTypeTemplateParmExprClass = 120, + ZigClangStmt_SubstNonTypeTemplateParmPackExprClass = 121, + ZigClangStmt_TypeTraitExprClass = 122, + ZigClangStmt_TypoExprClass = 123, + ZigClangStmt_UnaryExprOrTypeTraitExprClass = 124, + ZigClangStmt_UnaryOperatorClass = 125, + ZigClangStmt_VAArgExprClass = 126, + ZigClangStmt_ForStmtClass = 127, + ZigClangStmt_GotoStmtClass = 128, + ZigClangStmt_IfStmtClass = 129, + ZigClangStmt_IndirectGotoStmtClass = 130, + ZigClangStmt_LabelStmtClass = 131, + ZigClangStmt_MSDependentExistsStmtClass = 132, + ZigClangStmt_NullStmtClass = 133, + ZigClangStmt_OMPAtomicDirectiveClass = 134, + ZigClangStmt_OMPBarrierDirectiveClass = 135, + ZigClangStmt_OMPCancelDirectiveClass = 136, + ZigClangStmt_OMPCancellationPointDirectiveClass = 137, + ZigClangStmt_OMPCriticalDirectiveClass = 138, + ZigClangStmt_OMPFlushDirectiveClass = 139, + ZigClangStmt_OMPDistributeDirectiveClass = 140, + ZigClangStmt_OMPDistributeParallelForDirectiveClass = 141, + ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass = 142, + ZigClangStmt_OMPDistributeSimdDirectiveClass = 143, + ZigClangStmt_OMPForDirectiveClass = 144, + ZigClangStmt_OMPForSimdDirectiveClass = 145, + ZigClangStmt_OMPParallelForDirectiveClass = 146, + ZigClangStmt_OMPParallelForSimdDirectiveClass = 147, + ZigClangStmt_OMPSimdDirectiveClass = 148, + ZigClangStmt_OMPTargetParallelForSimdDirectiveClass = 149, + ZigClangStmt_OMPTargetSimdDirectiveClass = 150, + ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass = 151, + ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass = 152, + ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass = 153, + ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass = 154, + ZigClangStmt_OMPTaskLoopDirectiveClass = 155, + ZigClangStmt_OMPTaskLoopSimdDirectiveClass = 156, + ZigClangStmt_OMPTeamsDistributeDirectiveClass = 157, + ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass = 158, + ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass = 159, + ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass = 160, + ZigClangStmt_OMPMasterDirectiveClass = 161, + ZigClangStmt_OMPOrderedDirectiveClass = 162, + ZigClangStmt_OMPParallelDirectiveClass = 163, + ZigClangStmt_OMPParallelSectionsDirectiveClass = 164, + ZigClangStmt_OMPSectionDirectiveClass = 165, + ZigClangStmt_OMPSectionsDirectiveClass = 166, + ZigClangStmt_OMPSingleDirectiveClass = 167, + ZigClangStmt_OMPTargetDataDirectiveClass = 168, + ZigClangStmt_OMPTargetDirectiveClass = 169, + ZigClangStmt_OMPTargetEnterDataDirectiveClass = 170, + ZigClangStmt_OMPTargetExitDataDirectiveClass = 171, + ZigClangStmt_OMPTargetParallelDirectiveClass = 172, + ZigClangStmt_OMPTargetParallelForDirectiveClass = 173, + ZigClangStmt_OMPTargetTeamsDirectiveClass = 174, + ZigClangStmt_OMPTargetUpdateDirectiveClass = 175, + ZigClangStmt_OMPTaskDirectiveClass = 176, + ZigClangStmt_OMPTaskgroupDirectiveClass = 177, + ZigClangStmt_OMPTaskwaitDirectiveClass = 178, + ZigClangStmt_OMPTaskyieldDirectiveClass = 179, + ZigClangStmt_OMPTeamsDirectiveClass = 180, + ZigClangStmt_ObjCAtCatchStmtClass = 181, + ZigClangStmt_ObjCAtFinallyStmtClass = 182, + ZigClangStmt_ObjCAtSynchronizedStmtClass = 183, + ZigClangStmt_ObjCAtThrowStmtClass = 184, + ZigClangStmt_ObjCAtTryStmtClass = 185, + ZigClangStmt_ObjCAutoreleasePoolStmtClass = 186, + ZigClangStmt_ObjCForCollectionStmtClass = 187, + ZigClangStmt_ReturnStmtClass = 188, + ZigClangStmt_SEHExceptStmtClass = 189, + ZigClangStmt_SEHFinallyStmtClass = 190, + ZigClangStmt_SEHLeaveStmtClass = 191, + ZigClangStmt_SEHTryStmtClass = 192, + ZigClangStmt_CaseStmtClass = 193, + ZigClangStmt_DefaultStmtClass = 194, + ZigClangStmt_SwitchStmtClass = 195, + ZigClangStmt_WhileStmtClass = 196, +}; +pub const ZigClangCK_Dependent = enum_ZigClangCK._Dependent; +pub const ZigClangCK_BitCast = enum_ZigClangCK._BitCast; +pub const ZigClangCK_LValueBitCast = enum_ZigClangCK._LValueBitCast; +pub const ZigClangCK_LValueToRValue = enum_ZigClangCK._LValueToRValue; +pub const ZigClangCK_NoOp = enum_ZigClangCK._NoOp; +pub const ZigClangCK_BaseToDerived = enum_ZigClangCK._BaseToDerived; +pub const ZigClangCK_DerivedToBase = enum_ZigClangCK._DerivedToBase; +pub const ZigClangCK_UncheckedDerivedToBase = enum_ZigClangCK._UncheckedDerivedToBase; +pub const ZigClangCK_Dynamic = enum_ZigClangCK._Dynamic; +pub const ZigClangCK_ToUnion = enum_ZigClangCK._ToUnion; +pub const ZigClangCK_ArrayToPointerDecay = enum_ZigClangCK._ArrayToPointerDecay; +pub const ZigClangCK_FunctionToPointerDecay = enum_ZigClangCK._FunctionToPointerDecay; +pub const ZigClangCK_NullToPointer = enum_ZigClangCK._NullToPointer; +pub const ZigClangCK_NullToMemberPointer = enum_ZigClangCK._NullToMemberPointer; +pub const ZigClangCK_BaseToDerivedMemberPointer = enum_ZigClangCK._BaseToDerivedMemberPointer; +pub const ZigClangCK_DerivedToBaseMemberPointer = enum_ZigClangCK._DerivedToBaseMemberPointer; +pub const ZigClangCK_MemberPointerToBoolean = enum_ZigClangCK._MemberPointerToBoolean; +pub const ZigClangCK_ReinterpretMemberPointer = enum_ZigClangCK._ReinterpretMemberPointer; +pub const ZigClangCK_UserDefinedConversion = enum_ZigClangCK._UserDefinedConversion; +pub const ZigClangCK_ConstructorConversion = enum_ZigClangCK._ConstructorConversion; +pub const ZigClangCK_IntegralToPointer = enum_ZigClangCK._IntegralToPointer; +pub const ZigClangCK_PointerToIntegral = enum_ZigClangCK._PointerToIntegral; +pub const ZigClangCK_PointerToBoolean = enum_ZigClangCK._PointerToBoolean; +pub const ZigClangCK_ToVoid = enum_ZigClangCK._ToVoid; +pub const ZigClangCK_VectorSplat = enum_ZigClangCK._VectorSplat; +pub const ZigClangCK_IntegralCast = enum_ZigClangCK._IntegralCast; +pub const ZigClangCK_IntegralToBoolean = enum_ZigClangCK._IntegralToBoolean; +pub const ZigClangCK_IntegralToFloating = enum_ZigClangCK._IntegralToFloating; +pub const ZigClangCK_FixedPointCast = enum_ZigClangCK._FixedPointCast; +pub const ZigClangCK_FixedPointToBoolean = enum_ZigClangCK._FixedPointToBoolean; +pub const ZigClangCK_FloatingToIntegral = enum_ZigClangCK._FloatingToIntegral; +pub const ZigClangCK_FloatingToBoolean = enum_ZigClangCK._FloatingToBoolean; +pub const ZigClangCK_BooleanToSignedIntegral = enum_ZigClangCK._BooleanToSignedIntegral; +pub const ZigClangCK_FloatingCast = enum_ZigClangCK._FloatingCast; +pub const ZigClangCK_CPointerToObjCPointerCast = enum_ZigClangCK._CPointerToObjCPointerCast; +pub const ZigClangCK_BlockPointerToObjCPointerCast = enum_ZigClangCK._BlockPointerToObjCPointerCast; +pub const ZigClangCK_AnyPointerToBlockPointerCast = enum_ZigClangCK._AnyPointerToBlockPointerCast; +pub const ZigClangCK_ObjCObjectLValueCast = enum_ZigClangCK._ObjCObjectLValueCast; +pub const ZigClangCK_FloatingRealToComplex = enum_ZigClangCK._FloatingRealToComplex; +pub const ZigClangCK_FloatingComplexToReal = enum_ZigClangCK._FloatingComplexToReal; +pub const ZigClangCK_FloatingComplexToBoolean = enum_ZigClangCK._FloatingComplexToBoolean; +pub const ZigClangCK_FloatingComplexCast = enum_ZigClangCK._FloatingComplexCast; +pub const ZigClangCK_FloatingComplexToIntegralComplex = enum_ZigClangCK._FloatingComplexToIntegralComplex; +pub const ZigClangCK_IntegralRealToComplex = enum_ZigClangCK._IntegralRealToComplex; +pub const ZigClangCK_IntegralComplexToReal = enum_ZigClangCK._IntegralComplexToReal; +pub const ZigClangCK_IntegralComplexToBoolean = enum_ZigClangCK._IntegralComplexToBoolean; +pub const ZigClangCK_IntegralComplexCast = enum_ZigClangCK._IntegralComplexCast; +pub const ZigClangCK_IntegralComplexToFloatingComplex = enum_ZigClangCK._IntegralComplexToFloatingComplex; +pub const ZigClangCK_ARCProduceObject = enum_ZigClangCK._ARCProduceObject; +pub const ZigClangCK_ARCConsumeObject = enum_ZigClangCK._ARCConsumeObject; +pub const ZigClangCK_ARCReclaimReturnedObject = enum_ZigClangCK._ARCReclaimReturnedObject; +pub const ZigClangCK_ARCExtendBlockObject = enum_ZigClangCK._ARCExtendBlockObject; +pub const ZigClangCK_AtomicToNonAtomic = enum_ZigClangCK._AtomicToNonAtomic; +pub const ZigClangCK_NonAtomicToAtomic = enum_ZigClangCK._NonAtomicToAtomic; +pub const ZigClangCK_CopyAndAutoreleaseBlockObject = enum_ZigClangCK._CopyAndAutoreleaseBlockObject; +pub const ZigClangCK_BuiltinFnToFnPtr = enum_ZigClangCK._BuiltinFnToFnPtr; +pub const ZigClangCK_ZeroToOCLOpaqueType = enum_ZigClangCK._ZeroToOCLOpaqueType; +pub const ZigClangCK_AddressSpaceConversion = enum_ZigClangCK._AddressSpaceConversion; +pub const ZigClangCK_IntToOCLSampler = enum_ZigClangCK._IntToOCLSampler; +pub const enum_ZigClangCK = extern enum { + _Dependent, + _BitCast, + _LValueBitCast, + _LValueToRValue, + _NoOp, + _BaseToDerived, + _DerivedToBase, + _UncheckedDerivedToBase, + _Dynamic, + _ToUnion, + _ArrayToPointerDecay, + _FunctionToPointerDecay, + _NullToPointer, + _NullToMemberPointer, + _BaseToDerivedMemberPointer, + _DerivedToBaseMemberPointer, + _MemberPointerToBoolean, + _ReinterpretMemberPointer, + _UserDefinedConversion, + _ConstructorConversion, + _IntegralToPointer, + _PointerToIntegral, + _PointerToBoolean, + _ToVoid, + _VectorSplat, + _IntegralCast, + _IntegralToBoolean, + _IntegralToFloating, + _FixedPointCast, + _FixedPointToBoolean, + _FloatingToIntegral, + _FloatingToBoolean, + _BooleanToSignedIntegral, + _FloatingCast, + _CPointerToObjCPointerCast, + _BlockPointerToObjCPointerCast, + _AnyPointerToBlockPointerCast, + _ObjCObjectLValueCast, + _FloatingRealToComplex, + _FloatingComplexToReal, + _FloatingComplexToBoolean, + _FloatingComplexCast, + _FloatingComplexToIntegralComplex, + _IntegralRealToComplex, + _IntegralComplexToReal, + _IntegralComplexToBoolean, + _IntegralComplexCast, + _IntegralComplexToFloatingComplex, + _ARCProduceObject, + _ARCConsumeObject, + _ARCReclaimReturnedObject, + _ARCExtendBlockObject, + _AtomicToNonAtomic, + _NonAtomicToAtomic, + _CopyAndAutoreleaseBlockObject, + _BuiltinFnToFnPtr, + _ZeroToOCLOpaqueType, + _AddressSpaceConversion, + _IntToOCLSampler, +}; +pub const ZigClangAPValueUninitialized = enum_ZigClangAPValueKind.ZigClangAPValueUninitialized; +pub const ZigClangAPValueInt = enum_ZigClangAPValueKind.ZigClangAPValueInt; +pub const ZigClangAPValueFloat = enum_ZigClangAPValueKind.ZigClangAPValueFloat; +pub const ZigClangAPValueComplexInt = enum_ZigClangAPValueKind.ZigClangAPValueComplexInt; +pub const ZigClangAPValueComplexFloat = enum_ZigClangAPValueKind.ZigClangAPValueComplexFloat; +pub const ZigClangAPValueLValue = enum_ZigClangAPValueKind.ZigClangAPValueLValue; +pub const ZigClangAPValueVector = enum_ZigClangAPValueKind.ZigClangAPValueVector; +pub const ZigClangAPValueArray = enum_ZigClangAPValueKind.ZigClangAPValueArray; +pub const ZigClangAPValueStruct = enum_ZigClangAPValueKind.ZigClangAPValueStruct; +pub const ZigClangAPValueUnion = enum_ZigClangAPValueKind.ZigClangAPValueUnion; +pub const ZigClangAPValueMemberPointer = enum_ZigClangAPValueKind.ZigClangAPValueMemberPointer; +pub const ZigClangAPValueAddrLabelDiff = enum_ZigClangAPValueKind.ZigClangAPValueAddrLabelDiff; +pub const enum_ZigClangAPValueKind = extern enum { + ZigClangAPValueUninitialized, + ZigClangAPValueInt, + ZigClangAPValueFloat, + ZigClangAPValueComplexInt, + ZigClangAPValueComplexFloat, + ZigClangAPValueLValue, + ZigClangAPValueVector, + ZigClangAPValueArray, + ZigClangAPValueStruct, + ZigClangAPValueUnion, + ZigClangAPValueMemberPointer, + ZigClangAPValueAddrLabelDiff, +}; +pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation; +pub extern fn ZigClangSourceManager_getFilename(arg0: ?*const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) [*c]const u8; +pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; +pub extern fn ZigClangSourceManager_getSpellingColumnNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; +pub extern fn ZigClangSourceManager_getCharacterData(arg0: ?*const struct_ZigClangSourceManager, SL: struct_ZigClangSourceLocation) [*c]const u8; +pub extern fn ZigClangASTContext_getPointerType(arg0: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType; +pub extern fn ZigClangASTUnit_getASTContext(arg0: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext; +pub extern fn ZigClangASTUnit_getSourceManager(arg0: ?*struct_ZigClangASTUnit) ?*struct_ZigClangSourceManager; +pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(arg0: ?*struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, ?*const struct_ZigClangDecl) bool) bool; +pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) ?*const struct_ZigClangRecordDecl; +pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) ?*const struct_ZigClangEnumDecl; +pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl; +pub extern fn ZigClangEnumDecl_getCanonicalDecl(arg0: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl; +pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(arg0: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl; +pub extern fn ZigClangRecordDecl_getDefinition(arg0: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl; +pub extern fn ZigClangEnumDecl_getDefinition(arg0: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl; +pub extern fn ZigClangRecordDecl_getLocation(arg0: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation; +pub extern fn ZigClangEnumDecl_getLocation(arg0: ?*const struct_ZigClangEnumDecl) struct_ZigClangSourceLocation; +pub extern fn ZigClangTypedefNameDecl_getLocation(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangSourceLocation; +pub extern fn ZigClangRecordDecl_isUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool; +pub extern fn ZigClangRecordDecl_isStruct(record_decl: ?*const struct_ZigClangRecordDecl) bool; +pub extern fn ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool; +pub extern fn ZigClangEnumDecl_getIntegerType(arg0: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType; +pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8; +pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool; +pub extern fn ZigClangTypedefType_getDecl(arg0: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl; +pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType; +pub extern fn ZigClangQualType_getCanonicalType(arg0: struct_ZigClangQualType) struct_ZigClangQualType; +pub extern fn ZigClangQualType_getTypePtr(arg0: struct_ZigClangQualType) ?*const struct_ZigClangType; +pub extern fn ZigClangQualType_addConst(arg0: [*c]struct_ZigClangQualType) void; +pub extern fn ZigClangQualType_eq(arg0: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool; +pub extern fn ZigClangQualType_isConstQualified(arg0: struct_ZigClangQualType) bool; +pub extern fn ZigClangQualType_isVolatileQualified(arg0: struct_ZigClangQualType) bool; +pub extern fn ZigClangQualType_isRestrictQualified(arg0: struct_ZigClangQualType) bool; +pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) enum_ZigClangTypeClass; +pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool; +pub extern fn ZigClangType_getTypeClassName(self: ?*const struct_ZigClangType) [*c]const u8; +pub extern fn ZigClangStmt_getBeginLoc(self: ?*const struct_ZigClangStmt) struct_ZigClangSourceLocation; +pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) enum_ZigClangStmtClass; +pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool; +pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) enum_ZigClangStmtClass; +pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType; +pub extern fn ZigClangExpr_getBeginLoc(self: ?*const struct_ZigClangExpr) struct_ZigClangSourceLocation; +pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) enum_ZigClangAPValueKind; +pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt; +pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint; +pub extern fn ZigClangAPValue_getArrayInitializedElt(self: ?*const struct_ZigClangAPValue, i: c_uint) ?*const struct_ZigClangAPValue; +pub extern fn ZigClangAPValue_getArrayFiller(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPValue; +pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint; +pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase; +pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool; +pub extern fn ZigClangAPSInt_isNegative(self: ?*const struct_ZigClangAPSInt) bool; +pub extern fn ZigClangAPSInt_negate(self: ?*const struct_ZigClangAPSInt) ?*const struct_ZigClangAPSInt; +pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void; +pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64; +pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint; +pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr; +pub const ZigClangSourceLocation = struct_ZigClangSourceLocation; +pub const ZigClangQualType = struct_ZigClangQualType; +pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase; +pub const ZigClangAPValue = struct_ZigClangAPValue; +pub const ZigClangAPSInt = struct_ZigClangAPSInt; +pub const ZigClangASTContext = struct_ZigClangASTContext; +pub const ZigClangASTUnit = struct_ZigClangASTUnit; +pub const ZigClangArraySubscriptExpr = struct_ZigClangArraySubscriptExpr; +pub const ZigClangArrayType = struct_ZigClangArrayType; +pub const ZigClangAttributedType = struct_ZigClangAttributedType; +pub const ZigClangBinaryOperator = struct_ZigClangBinaryOperator; +pub const ZigClangBreakStmt = struct_ZigClangBreakStmt; +pub const ZigClangBuiltinType = struct_ZigClangBuiltinType; +pub const ZigClangCStyleCastExpr = struct_ZigClangCStyleCastExpr; +pub const ZigClangCallExpr = struct_ZigClangCallExpr; +pub const ZigClangCaseStmt = struct_ZigClangCaseStmt; +pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator; +pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt; +pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator; +pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType; +pub const ZigClangContinueStmt = struct_ZigClangContinueStmt; +pub const ZigClangDecayedType = struct_ZigClangDecayedType; +pub const ZigClangDecl = struct_ZigClangDecl; +pub const ZigClangDeclRefExpr = struct_ZigClangDeclRefExpr; +pub const ZigClangDeclStmt = struct_ZigClangDeclStmt; +pub const ZigClangDefaultStmt = struct_ZigClangDefaultStmt; +pub const ZigClangDiagnosticOptions = struct_ZigClangDiagnosticOptions; +pub const ZigClangDiagnosticsEngine = struct_ZigClangDiagnosticsEngine; +pub const ZigClangDoStmt = struct_ZigClangDoStmt; +pub const ZigClangElaboratedType = struct_ZigClangElaboratedType; +pub const ZigClangEnumConstantDecl = struct_ZigClangEnumConstantDecl; +pub const ZigClangEnumDecl = struct_ZigClangEnumDecl; +pub const ZigClangEnumType = struct_ZigClangEnumType; +pub const ZigClangExpr = struct_ZigClangExpr; +pub const ZigClangFieldDecl = struct_ZigClangFieldDecl; +pub const ZigClangFileID = struct_ZigClangFileID; +pub const ZigClangForStmt = struct_ZigClangForStmt; +pub const ZigClangFullSourceLoc = struct_ZigClangFullSourceLoc; +pub const ZigClangFunctionDecl = struct_ZigClangFunctionDecl; +pub const ZigClangFunctionProtoType = struct_ZigClangFunctionProtoType; +pub const ZigClangIfStmt = struct_ZigClangIfStmt; +pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr; +pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType; +pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral; +pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord; +pub const ZigClangMemberExpr = struct_ZigClangMemberExpr; +pub const ZigClangNamedDecl = struct_ZigClangNamedDecl; +pub const ZigClangNone = struct_ZigClangNone; +pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations; +pub const ZigClangParenExpr = struct_ZigClangParenExpr; +pub const ZigClangParenType = struct_ZigClangParenType; +pub const ZigClangParmVarDecl = struct_ZigClangParmVarDecl; +pub const ZigClangPointerType = struct_ZigClangPointerType; +pub const ZigClangPreprocessedEntity = struct_ZigClangPreprocessedEntity; +pub const ZigClangRecordDecl = struct_ZigClangRecordDecl; +pub const ZigClangRecordType = struct_ZigClangRecordType; +pub const ZigClangReturnStmt = struct_ZigClangReturnStmt; +pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope; +pub const ZigClangSourceManager = struct_ZigClangSourceManager; +pub const ZigClangSourceRange = struct_ZigClangSourceRange; +pub const ZigClangStmt = struct_ZigClangStmt; +pub const ZigClangStorageClass = struct_ZigClangStorageClass; +pub const ZigClangStringLiteral = struct_ZigClangStringLiteral; +pub const ZigClangStringRef = struct_ZigClangStringRef; +pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt; +pub const ZigClangTagDecl = struct_ZigClangTagDecl; +pub const ZigClangType = struct_ZigClangType; +pub const ZigClangTypedefNameDecl = struct_ZigClangTypedefNameDecl; +pub const ZigClangTypedefType = struct_ZigClangTypedefType; +pub const ZigClangUnaryExprOrTypeTraitExpr = struct_ZigClangUnaryExprOrTypeTraitExpr; +pub const ZigClangUnaryOperator = struct_ZigClangUnaryOperator; +pub const ZigClangValueDecl = struct_ZigClangValueDecl; +pub const ZigClangVarDecl = struct_ZigClangVarDecl; +pub const ZigClangWhileStmt = struct_ZigClangWhileStmt; +pub const ZigClangBO = enum_ZigClangBO; +pub const ZigClangUO = enum_ZigClangUO; +pub const ZigClangTypeClass = enum_ZigClangTypeClass; +pub const ZigClangStmtClass = enum_ZigClangStmtClass; +pub const ZigClangCK = enum_ZigClangCK; +pub const ZigClangAPValueKind = enum_ZigClangAPValueKind; diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig index f87c8a0e70..cf5f06c285 100644 --- a/src-self-hosted/stage1.zig +++ b/src-self-hosted/stage1.zig @@ -1,8 +1,7 @@ // This is Zig code that is used by both stage1 and stage2. // The prototypes in src/userland.h must match these definitions. -comptime { - _ = @import("translate_c.zig"); -} + +const std = @import("std"); pub const info_zen = \\ @@ -29,3 +28,93 @@ export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { export fn stage2_panic(ptr: [*]const u8, len: usize) void { @panic(ptr[0..len]); } + +const TranslateMode = extern enum { + import, + translate, +}; + +const Error = extern enum { + None, + OutOfMemory, + InvalidFormat, + SemanticAnalyzeFail, + AccessDenied, + Interrupted, + SystemResources, + FileNotFound, + FileSystem, + FileTooBig, + DivByZero, + Overflow, + PathAlreadyExists, + Unexpected, + ExactDivRemainder, + NegativeDenominator, + ShiftedOutOneBits, + CCompileErrors, + EndOfFile, + IsDir, + NotDir, + UnsupportedOperatingSystem, + SharingViolation, + PipeBusy, + PrimitiveTypeNotFound, + CacheUnavailable, + PathTooLong, + CCompilerCannotFindFile, + ReadingDepFile, + InvalidDepFile, + MissingArchitecture, + MissingOperatingSystem, + UnknownArchitecture, + UnknownOperatingSystem, + UnknownABI, + InvalidFilename, + DiskQuota, + DiskSpace, + UnexpectedWriteFailure, + UnexpectedSeekFailure, + UnexpectedFileTruncationFailure, + Unimplemented, + OperationAborted, + BrokenPipe, + NoSpaceLeft, +}; + +const FILE = std.c.FILE; +const ast = std.zig.ast; + +/// Args should have a null terminating last arg. +export fn stage2_translate_c( + out_ast: **ast.Tree, + args_begin: [*]?[*]const u8, + args_end: [*]?[*]const u8, + mode: TranslateMode, +) Error { + const translate_c = @import("translate_c.zig"); + out_ast.* = translate_c.translate(args_begin, args_end, switch (mode) { + .import => translate_c.Mode.import, + .translate => translate_c.Mode.translate, + }) catch |err| switch (err) { + error.Unimplemented => return Error.Unimplemented, + }; + return Error.None; +} + +export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error { + const c_out_stream = &std.io.COutStream.init(output_file).stream; + _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) { + error.SystemResources => return Error.SystemResources, + error.OperationAborted => return Error.OperationAborted, + error.BrokenPipe => return Error.BrokenPipe, + error.DiskQuota => return Error.DiskQuota, + error.FileTooBig => return Error.FileTooBig, + error.NoSpaceLeft => return Error.NoSpaceLeft, + error.AccessDenied => return Error.AccessDenied, + error.OutOfMemory => return Error.OutOfMemory, + error.Unexpected => return Error.Unexpected, + error.InputOutput => return Error.FileSystem, + }; + return Error.None; +} diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index e182a5a994..c2d943b1ff 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -2,7 +2,14 @@ // and stage2. Currently it's not used by anything, as it's not feature complete. const std = @import("std"); +const ast = std.zig.ast; +use @import("clang.zig"); -export fn stage2_translate_c() void { - std.debug.panic("unimplemented"); +pub const Mode = enum { + import, + translate, +}; + +pub fn translate(args_begin: [*]?[*]const u8, args_end: [*]?[*]const u8, mode: Mode) !*ast.Tree { + return error.Unimplemented; } diff --git a/src/analyze.cpp b/src/analyze.cpp index 64cf8f2321..158a4bc94f 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3725,7 +3725,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) { } if (g->verbose_ir) { fprintf(stderr, "\n"); - ast_render(g, stderr, fn_table_entry->body_node, 4); + ast_render(stderr, fn_table_entry->body_node, 4); fprintf(stderr, "\n{ // (IR)\n"); ir_print(g, stderr, &fn_table_entry->ir_executable, 4); fprintf(stderr, "}\n"); diff --git a/src/analyze.hpp b/src/analyze.hpp index a3246fdf4d..cde9f2d321 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -247,4 +247,6 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type); ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type); +void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c); + #endif diff --git a/src/ast_render.cpp b/src/ast_render.cpp index f66a47600e..95ae216f70 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -296,7 +296,6 @@ void ast_print(FILE *f, AstNode *node, int indent) { struct AstRender { - CodeGen *codegen; int indent; int indent_size; FILE *f; @@ -1170,9 +1169,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { } -void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) { +void ast_render(FILE *f, AstNode *node, int indent_size) { AstRender ar = {0}; - ar.codegen = codegen; ar.f = f; ar.indent_size = indent_size; ar.indent = 0; diff --git a/src/ast_render.hpp b/src/ast_render.hpp index 1652156eee..cf70b04694 100644 --- a/src/ast_render.hpp +++ b/src/ast_render.hpp @@ -15,6 +15,6 @@ void ast_print(FILE *f, AstNode *node, int indent); -void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size); +void ast_render(FILE *f, AstNode *node, int indent_size); #endif diff --git a/src/codegen.cpp b/src/codegen.cpp index 6075fb6881..b4ea0a9a96 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8153,7 +8153,128 @@ static void detect_libc(CodeGen *g) { } } -AstNode *codegen_translate_c(CodeGen *g, Buf *full_path, bool use_userland_implementation) { +// does not add the "cc" arg +void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c) { + if (out_dep_path != nullptr) { + args.append("-MD"); + args.append("-MV"); + args.append("-MF"); + args.append(out_dep_path); + } + + args.append("-nostdinc"); + args.append("-fno-spell-checking"); + + if (translate_c) { + // TODO these args shouldn't be special from the non-translate-c args, probably. + args.append("-nobuiltininc"); + args.append("-nostdinc++"); + if (g->libc_link_lib == nullptr) { + args.append("-nolibc"); + } + + // this gives us access to preprocessing entities, presumably at + // the cost of performance + args.append("-Xclang"); + args.append("-detailed-preprocessing-record"); + } else { + 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; + } + } + + 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) { + Buf *include_dir = g->libc_include_dir_list[i]; + args.append("-isystem"); + args.append(buf_ptr(include_dir)); + } + + if (g->zig_target->is_native) { + args.append("-march=native"); + } else { + args.append("-target"); + args.append(buf_ptr(&g->triple_str)); + } + if (g->zig_target->os == OsFreestanding) { + args.append("-ffreestanding"); + } + + if (!g->strip_debug_symbols) { + args.append("-g"); + } + + switch (g->build_mode) { + case BuildModeDebug: + // windows c runtime requires -D_DEBUG if using debug libraries + args.append("-D_DEBUG"); + + 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"); + } + args.append("-fno-omit-frame-pointer"); + 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"); + } + args.append("-fomit-frame-pointer"); + 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"); + args.append("-fomit-frame-pointer"); + break; + case BuildModeSmallRelease: + args.append("-DNDEBUG"); + args.append("-Os"); + args.append("-fno-stack-protector"); + args.append("-fomit-frame-pointer"); + 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, FILE *out_file, bool use_userland_implementation) { + Error err; Buf *src_basename = buf_alloc(); Buf *src_dirname = buf_alloc(); os_path_split(full_path, src_dirname, src_basename); @@ -8165,30 +8286,45 @@ AstNode *codegen_translate_c(CodeGen *g, Buf *full_path, bool use_userland_imple init(g); + Stage2TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ? + Stage2TranslateModeImport : Stage2TranslateModeTranslate; + + + ZigList clang_argv = {0}; + add_cc_args(g, clang_argv, nullptr, true); + + clang_argv.append("-c"); + clang_argv.append(buf_ptr(full_path)); + + clang_argv.append(nullptr); // to make the [start...end] argument work + if (use_userland_implementation) { - // TODO improve this - stage2_translate_c(); - zig_panic("TODO"); - } + Stage2Ast *ast; + if ((err = stage2_translate_c(&ast, &clang_argv.at(0), &clang_argv.last(), trans_mode))) { + zig_panic("TODO"); + } + stage2_render_ast(ast, out_file); + } else { + ZigList errors = {0}; + AstNode *root_node; - ZigList errors = {0}; - AstNode *root_node; - Error err = parse_h_file(&root_node, &errors, buf_ptr(full_path), g, nullptr); + err = parse_h_file(g, &root_node, &clang_argv.at(0), &clang_argv.last(), trans_mode, &errors); - if (err == ErrorCCompileErrors && errors.length > 0) { - for (size_t i = 0; i < errors.length; i += 1) { - ErrorMsg *err_msg = errors.at(i); - print_err_msg(err_msg, g->err_color); + if (err == ErrorCCompileErrors && errors.length > 0) { + for (size_t i = 0; i < errors.length; i += 1) { + ErrorMsg *err_msg = errors.at(i); + print_err_msg(err_msg, g->err_color); + } + exit(1); } - exit(1); - } - if (err) { - fprintf(stderr, "unable to parse C file: %s\n", err_str(err)); - exit(1); - } + if (err) { + fprintf(stderr, "unable to parse C file: %s\n", err_str(err)); + exit(1); + } - return root_node; + ast_render(out_file, root_node, 4); + } } static ZigType *add_special_code(CodeGen *g, ZigPackage *package, const char *basename) { @@ -8507,93 +8643,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { args.append("cc"); Buf *out_dep_path = buf_sprintf("%s.d", buf_ptr(out_obj_path)); - args.append("-MD"); - args.append("-MV"); - args.append("-MF"); - args.append(buf_ptr(out_dep_path)); - - args.append("-nostdinc"); - args.append("-fno-spell-checking"); - - 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; - } - - 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) { - Buf *include_dir = g->libc_include_dir_list[i]; - args.append("-isystem"); - args.append(buf_ptr(include_dir)); - } - - if (g->zig_target->is_native) { - args.append("-march=native"); - } else { - args.append("-target"); - args.append(buf_ptr(&g->triple_str)); - } - if (g->zig_target->os == OsFreestanding) { - args.append("-ffreestanding"); - } - - if (!g->strip_debug_symbols) { - args.append("-g"); - } - - switch (g->build_mode) { - case BuildModeDebug: - 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"); - } - args.append("-fno-omit-frame-pointer"); - 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"); - } - args.append("-fomit-frame-pointer"); - 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"); - args.append("-fomit-frame-pointer"); - break; - case BuildModeSmallRelease: - args.append("-DNDEBUG"); - args.append("-Os"); - args.append("-fno-stack-protector"); - args.append("-fomit-frame-pointer"); - break; - } + add_cc_args(g, args, buf_ptr(out_dep_path), false); args.append("-o"); args.append(buf_ptr(out_obj_path)); @@ -8601,19 +8651,10 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { args.append("-c"); args.append(buf_ptr(c_source_file)); - 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]); - } - 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("zig", &args); } diff --git a/src/codegen.hpp b/src/codegen.hpp index d6149bf5d2..88c7353cad 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -12,6 +12,7 @@ #include "errmsg.hpp" #include "target.hpp" #include "libc_installation.hpp" +#include "userland.h" #include @@ -50,7 +51,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c void codegen_add_assembly(CodeGen *g, Buf *path); void codegen_add_object(CodeGen *g, Buf *object_path); -AstNode *codegen_translate_c(CodeGen *g, Buf *path, bool use_userland_implementation); +void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation); Buf *codegen_generate_builtin_source(CodeGen *g); diff --git a/src/error.cpp b/src/error.cpp index 84b78aba1b..69676f9cf5 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -50,6 +50,10 @@ const char *err_str(Error err) { case ErrorUnexpectedWriteFailure: return "unexpected write failure"; case ErrorUnexpectedSeekFailure: return "unexpected seek failure"; case ErrorUnexpectedFileTruncationFailure: return "unexpected file truncation failure"; + case ErrorUnimplemented: return "unimplemented"; + case ErrorOperationAborted: return "operation aborted"; + case ErrorBrokenPipe: return "broken pipe"; + case ErrorNoSpaceLeft: return "no space left"; } return "(invalid error)"; } diff --git a/src/error.hpp b/src/error.hpp index 75ee801112..3ff36e1a5f 100644 --- a/src/error.hpp +++ b/src/error.hpp @@ -8,49 +8,7 @@ #ifndef ERROR_HPP #define ERROR_HPP -enum Error { - ErrorNone, - ErrorNoMem, - ErrorInvalidFormat, - ErrorSemanticAnalyzeFail, - ErrorAccess, - ErrorInterrupted, - ErrorSystemResources, - ErrorFileNotFound, - ErrorFileSystem, - ErrorFileTooBig, - ErrorDivByZero, - ErrorOverflow, - ErrorPathAlreadyExists, - ErrorUnexpected, - ErrorExactDivRemainder, - ErrorNegativeDenominator, - ErrorShiftedOutOneBits, - ErrorCCompileErrors, - ErrorEndOfFile, - ErrorIsDir, - ErrorNotDir, - ErrorUnsupportedOperatingSystem, - ErrorSharingViolation, - ErrorPipeBusy, - ErrorPrimitiveTypeNotFound, - ErrorCacheUnavailable, - ErrorPathTooLong, - ErrorCCompilerCannotFindFile, - ErrorReadingDepFile, - ErrorInvalidDepFile, - ErrorMissingArchitecture, - ErrorMissingOperatingSystem, - ErrorUnknownArchitecture, - ErrorUnknownOperatingSystem, - ErrorUnknownABI, - ErrorInvalidFilename, - ErrorDiskQuota, - ErrorDiskSpace, - ErrorUnexpectedWriteFailure, - ErrorUnexpectedSeekFailure, - ErrorUnexpectedFileTruncationFailure, -}; +#include "userland.h" const char *err_str(Error err); diff --git a/src/ir.cpp b/src/ir.cpp index 62eadeb43f..105dd0c3d6 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10350,7 +10350,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod if (codegen->verbose_ir) { fprintf(stderr, "\nSource: "); - ast_render(codegen, stderr, node, 4); + ast_render(stderr, node, 4); fprintf(stderr, "\n{ // (IR)\n"); ir_print(codegen, stderr, ir_executable, 2); fprintf(stderr, "}\n"); @@ -19092,11 +19092,23 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); } - ZigList errors = {0}; - Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path)); + + ZigList clang_argv = {0}; + + add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true); + + clang_argv.append("-c"); + clang_argv.append(buf_ptr(&tmp_c_file_path)); + + clang_argv.append(nullptr); // to make the [start...end] argument work + + ZigList errors = {0}; AstNode *root_node; - if ((err = parse_h_file(&root_node, &errors, buf_ptr(&tmp_c_file_path), ira->codegen, tmp_dep_file))) { + + if ((err = parse_h_file(ira->codegen, &root_node, &clang_argv.at(0), &clang_argv.last(), + Stage2TranslateModeImport, &errors))) + { if (err != ErrorCCompileErrors) { ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); return ira->codegen->invalid_instruction; @@ -19139,7 +19151,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); return ira->codegen->invalid_instruction; } - ast_render(ira->codegen, out_file, root_node, 4); + ast_render(out_file, root_node, 4); if (fclose(out_file) != 0) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); diff --git a/src/main.cpp b/src/main.cpp index 8cbc9b0d8c..2b65999e3b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1188,8 +1188,7 @@ int main(int argc, char **argv) { zig_unreachable(); } } else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) { - AstNode *root_node = codegen_translate_c(g, in_file_buf, cmd == CmdTranslateCUserland); - ast_render(g, stdout, root_node, 4); + codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland); if (timing_info) codegen_print_timing_report(g, stderr); return EXIT_SUCCESS; diff --git a/src/translate_c.cpp b/src/translate_c.cpp index f4f1055ed9..d19083ce73 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -5018,14 +5018,14 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) { } } -Error parse_h_file(AstNode **out_root_node, ZigList *errors, const char *target_file, - CodeGen *codegen, Buf *tmp_dep_file) +Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_begin, const char **args_end, + Stage2TranslateMode mode, ZigList *errors) { Context context = {0}; Context *c = &context; c->warnings_on = codegen->verbose_cimport; c->errors = errors; - if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) { + if (mode == Stage2TranslateModeImport) { c->visib_mod = VisibModPub; c->want_export = false; } else { @@ -5039,92 +5039,6 @@ Error parse_h_file(AstNode **out_root_node, ZigList *errors, const c c->codegen = codegen; c->global_scope = trans_scope_root_create(c); - ZigList clang_argv = {0}; - - clang_argv.append("-x"); - clang_argv.append("c"); - - if (tmp_dep_file != nullptr) { - clang_argv.append("-MD"); - clang_argv.append("-MV"); - clang_argv.append("-MF"); - clang_argv.append(buf_ptr(tmp_dep_file)); - } - - if (c->codegen->zig_target->is_native) { - char *ZIG_PARSEC_CFLAGS = getenv("ZIG_NATIVE_PARSEC_CFLAGS"); - if (ZIG_PARSEC_CFLAGS) { - Buf tmp_buf = BUF_INIT; - char *start = ZIG_PARSEC_CFLAGS; - char *space = strstr(start, " "); - while (space) { - if (space - start > 0) { - buf_init_from_mem(&tmp_buf, start, space - start); - clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf))); - } - start = space + 1; - space = strstr(start, " "); - } - buf_init_from_str(&tmp_buf, start); - clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf))); - } - } - - clang_argv.append("-nobuiltininc"); - clang_argv.append("-nostdinc"); - clang_argv.append("-nostdinc++"); - if (codegen->libc_link_lib == nullptr) { - clang_argv.append("-nolibc"); - } - - clang_argv.append("-isystem"); - clang_argv.append(buf_ptr(codegen->zig_c_headers_dir)); - - for (size_t i = 0; i < codegen->libc_include_dir_len; i += 1) { - Buf *include_dir = codegen->libc_include_dir_list[i]; - clang_argv.append("-isystem"); - clang_argv.append(buf_ptr(include_dir)); - } - - // windows c runtime requires -D_DEBUG if using debug libraries - if (codegen->build_mode == BuildModeDebug) { - clang_argv.append("-D_DEBUG"); - } - - for (size_t i = 0; i < codegen->clang_argv_len; i += 1) { - clang_argv.append(codegen->clang_argv[i]); - } - - // we don't need spell checking and it slows things down - clang_argv.append("-fno-spell-checking"); - - // this gives us access to preprocessing entities, presumably at - // the cost of performance - clang_argv.append("-Xclang"); - clang_argv.append("-detailed-preprocessing-record"); - - if (c->codegen->zig_target->is_native) { - clang_argv.append("-march=native"); - } else { - clang_argv.append("-target"); - clang_argv.append(buf_ptr(&c->codegen->triple_str)); - } - if (c->codegen->zig_target->os == OsFreestanding) { - clang_argv.append("-ffreestanding"); - } - - clang_argv.append(target_file); - - if (codegen->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"); - } - - // to make the [start...end] argument work - clang_argv.append(nullptr); clang::IntrusiveRefCntPtr diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions)); @@ -5139,7 +5053,7 @@ Error parse_h_file(AstNode **out_root_node, ZigList *errors, const c const char *resources_path = buf_ptr(codegen->zig_c_headers_dir); std::unique_ptr err_unit; ZigClangASTUnit *ast_unit = reinterpret_cast(clang::ASTUnit::LoadFromCommandLine( - &clang_argv.at(0), &clang_argv.last(), + args_begin, args_end, pch_container_ops, diags, resources_path, only_local_decls, capture_diagnostics, clang::None, true, 0, clang::TU_Complete, false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None, diff --git a/src/translate_c.hpp b/src/translate_c.hpp index 21461d2813..b6e4b6bcbb 100644 --- a/src/translate_c.hpp +++ b/src/translate_c.hpp @@ -11,7 +11,7 @@ #include "all_types.hpp" -Error parse_h_file(AstNode **out_root_node, ZigList *errors, const char *target_file, - CodeGen *codegen, Buf *tmp_dep_file); +Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_begin, const char **args_end, + Stage2TranslateMode mode, ZigList *errors); #endif diff --git a/src/userland.cpp b/src/userland.cpp index 6c56bceaa0..9935d5c04a 100644 --- a/src/userland.cpp +++ b/src/userland.cpp @@ -2,11 +2,14 @@ // src-self-hosted/stage1.zig #include "userland.h" +#include "ast_render.hpp" #include #include #include -void stage2_translate_c(void) { +Error stage2_translate_c(struct Stage2Ast **out_ast, + const char **args_begin, const char **args_end, enum Stage2TranslateMode mode) +{ const char *msg = "stage0 called stage2_translate_c"; stage2_panic(msg, strlen(msg)); } @@ -22,3 +25,8 @@ void stage2_panic(const char *ptr, size_t len) { fflush(stderr); abort(); } + +void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) { + const char *msg = "stage0 called stage2_render_ast"; + stage2_panic(msg, strlen(msg)); +} diff --git a/src/userland.h b/src/userland.h index a01bcc62c3..35fd46942b 100644 --- a/src/userland.h +++ b/src/userland.h @@ -9,6 +9,7 @@ #define ZIG_USERLAND_H #include +#include #ifdef __cplusplus #define ZIG_USERLAND_EXTERN_C extern "C" @@ -16,10 +17,77 @@ #define ZIG_USERLAND_EXTERN_C #endif -ZIG_USERLAND_EXTERN_C void stage2_translate_c(void); +#if defined(_MSC_VER) +#define ZIG_USERLAND_ATTRIBUTE_NORETURN __declspec(noreturn) +#else +#define ZIG_USERLAND_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#endif + +// The types and declarations in this file must match both those in userland.cpp and +// src-self-hosted/stage1.zig. + +enum Error { + ErrorNone, + ErrorNoMem, + ErrorInvalidFormat, + ErrorSemanticAnalyzeFail, + ErrorAccess, + ErrorInterrupted, + ErrorSystemResources, + ErrorFileNotFound, + ErrorFileSystem, + ErrorFileTooBig, + ErrorDivByZero, + ErrorOverflow, + ErrorPathAlreadyExists, + ErrorUnexpected, + ErrorExactDivRemainder, + ErrorNegativeDenominator, + ErrorShiftedOutOneBits, + ErrorCCompileErrors, + ErrorEndOfFile, + ErrorIsDir, + ErrorNotDir, + ErrorUnsupportedOperatingSystem, + ErrorSharingViolation, + ErrorPipeBusy, + ErrorPrimitiveTypeNotFound, + ErrorCacheUnavailable, + ErrorPathTooLong, + ErrorCCompilerCannotFindFile, + ErrorReadingDepFile, + ErrorInvalidDepFile, + ErrorMissingArchitecture, + ErrorMissingOperatingSystem, + ErrorUnknownArchitecture, + ErrorUnknownOperatingSystem, + ErrorUnknownABI, + ErrorInvalidFilename, + ErrorDiskQuota, + ErrorDiskSpace, + ErrorUnexpectedWriteFailure, + ErrorUnexpectedSeekFailure, + ErrorUnexpectedFileTruncationFailure, + ErrorUnimplemented, + ErrorOperationAborted, + ErrorBrokenPipe, + ErrorNoSpaceLeft, +}; + +enum Stage2TranslateMode { + Stage2TranslateModeImport, + Stage2TranslateModeTranslate, +}; + +struct Stage2Ast; + +ZIG_USERLAND_EXTERN_C Error stage2_translate_c(struct Stage2Ast **out_ast, + const char **args_begin, const char **args_end, enum Stage2TranslateMode mode); + +ZIG_USERLAND_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file); ZIG_USERLAND_EXTERN_C void stage2_zen(const char **ptr, size_t *len); -ZIG_USERLAND_EXTERN_C void stage2_panic(const char *ptr, size_t len); +ZIG_USERLAND_EXTERN_C ZIG_USERLAND_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); #endif diff --git a/src/zig_clang.h b/src/zig_clang.h index 78d6e1589d..148ee34f51 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -9,6 +9,7 @@ #define ZIG_ZIG_CLANG_H #include +#include #ifdef __cplusplus #define ZIG_EXTERN_C extern "C" @@ -17,8 +18,8 @@ #endif // ATTENTION: If you modify this file, be sure to update the corresponding -// extern function declarations in the self-hosted compiler. -// Note: not yet, we don't have the corresponding clang.zig yet. +// extern function declarations in the self-hosted compiler file +// src-self-hosted/clang.zig. struct ZigClangSourceLocation { unsigned ID; @@ -486,86 +487,86 @@ enum ZigClangAPValueKind { ZigClangAPValueAddrLabelDiff, }; -ZIG_EXTERN_C ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *, - ZigClangSourceLocation Loc); -ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const ZigClangSourceManager *, - ZigClangSourceLocation SpellingLoc); -ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingLineNumber(const ZigClangSourceManager *, - ZigClangSourceLocation Loc); -ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingColumnNumber(const ZigClangSourceManager *, - ZigClangSourceLocation Loc); -ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const ZigClangSourceManager *, - ZigClangSourceLocation SL); - -ZIG_EXTERN_C ZigClangQualType ZigClangASTContext_getPointerType(const ZigClangASTContext*, ZigClangQualType T); - -ZIG_EXTERN_C ZigClangASTContext *ZigClangASTUnit_getASTContext(ZigClangASTUnit *); -ZIG_EXTERN_C ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *); -ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *, void *context, - bool (*Fn)(void *context, const ZigClangDecl *decl)); - -ZIG_EXTERN_C const ZigClangRecordDecl *ZigClangRecordType_getDecl(const ZigClangRecordType *record_ty); -ZIG_EXTERN_C const ZigClangEnumDecl *ZigClangEnumType_getDecl(const ZigClangEnumType *record_ty); - -ZIG_EXTERN_C const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordDecl *record_decl); -ZIG_EXTERN_C const ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const ZigClangEnumDecl *); -ZIG_EXTERN_C const ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const ZigClangTypedefNameDecl *); - -ZIG_EXTERN_C const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *); -ZIG_EXTERN_C const ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const ZigClangEnumDecl *); - -ZIG_EXTERN_C ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *); -ZIG_EXTERN_C ZigClangSourceLocation ZigClangEnumDecl_getLocation(const ZigClangEnumDecl *); -ZIG_EXTERN_C ZigClangSourceLocation ZigClangTypedefNameDecl_getLocation(const ZigClangTypedefNameDecl *); - -ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const ZigClangRecordDecl *record_decl); -ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const ZigClangRecordDecl *record_decl); -ZIG_EXTERN_C bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *record_decl); - -ZIG_EXTERN_C ZigClangQualType ZigClangEnumDecl_getIntegerType(const ZigClangEnumDecl *); - -ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *decl); - -ZIG_EXTERN_C bool ZigClangSourceLocation_eq(ZigClangSourceLocation a, ZigClangSourceLocation b); - -ZIG_EXTERN_C const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *); -ZIG_EXTERN_C ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(const ZigClangTypedefNameDecl *); - -ZIG_EXTERN_C ZigClangQualType ZigClangQualType_getCanonicalType(ZigClangQualType); -ZIG_EXTERN_C const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType); -ZIG_EXTERN_C void ZigClangQualType_addConst(ZigClangQualType *); -ZIG_EXTERN_C bool ZigClangQualType_eq(ZigClangQualType, ZigClangQualType); -ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(ZigClangQualType); -ZIG_EXTERN_C bool ZigClangQualType_isVolatileQualified(ZigClangQualType); -ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(ZigClangQualType); - -ZIG_EXTERN_C ZigClangTypeClass ZigClangType_getTypeClass(const ZigClangType *self); -ZIG_EXTERN_C bool ZigClangType_isVoidType(const ZigClangType *self); -ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const ZigClangType *self); - -ZIG_EXTERN_C ZigClangSourceLocation ZigClangStmt_getBeginLoc(const ZigClangStmt *self); -ZIG_EXTERN_C ZigClangStmtClass ZigClangStmt_getStmtClass(const ZigClangStmt *self); -ZIG_EXTERN_C bool ZigClangStmt_classof_Expr(const ZigClangStmt *self); - -ZIG_EXTERN_C ZigClangStmtClass ZigClangExpr_getStmtClass(const ZigClangExpr *self); -ZIG_EXTERN_C ZigClangQualType ZigClangExpr_getType(const ZigClangExpr *self); -ZIG_EXTERN_C ZigClangSourceLocation ZigClangExpr_getBeginLoc(const ZigClangExpr *self); - -ZIG_EXTERN_C ZigClangAPValueKind ZigClangAPValue_getKind(const ZigClangAPValue *self); -ZIG_EXTERN_C const ZigClangAPSInt *ZigClangAPValue_getInt(const ZigClangAPValue *self); -ZIG_EXTERN_C unsigned ZigClangAPValue_getArrayInitializedElts(const ZigClangAPValue *self); -ZIG_EXTERN_C const ZigClangAPValue *ZigClangAPValue_getArrayInitializedElt(const ZigClangAPValue *self, unsigned i); -ZIG_EXTERN_C const ZigClangAPValue *ZigClangAPValue_getArrayFiller(const ZigClangAPValue *self); -ZIG_EXTERN_C unsigned ZigClangAPValue_getArraySize(const ZigClangAPValue *self); -ZIG_EXTERN_C ZigClangAPValueLValueBase ZigClangAPValue_getLValueBase(const ZigClangAPValue *self); - -ZIG_EXTERN_C bool ZigClangAPSInt_isSigned(const ZigClangAPSInt *self); -ZIG_EXTERN_C bool ZigClangAPSInt_isNegative(const ZigClangAPSInt *self); -ZIG_EXTERN_C const ZigClangAPSInt *ZigClangAPSInt_negate(const ZigClangAPSInt *self); -ZIG_EXTERN_C void ZigClangAPSInt_free(const ZigClangAPSInt *self); -ZIG_EXTERN_C const uint64_t *ZigClangAPSInt_getRawData(const ZigClangAPSInt *self); -ZIG_EXTERN_C unsigned ZigClangAPSInt_getNumWords(const ZigClangAPSInt *self); - -ZIG_EXTERN_C const ZigClangExpr *ZigClangAPValueLValueBase_dyn_cast_Expr(ZigClangAPValueLValueBase self); +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *, + struct ZigClangSourceLocation Loc); +ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const struct ZigClangSourceManager *, + struct ZigClangSourceLocation SpellingLoc); +ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingLineNumber(const struct ZigClangSourceManager *, + struct ZigClangSourceLocation Loc); +ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingColumnNumber(const struct ZigClangSourceManager *, + struct ZigClangSourceLocation Loc); +ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const struct ZigClangSourceManager *, + struct ZigClangSourceLocation SL); + +ZIG_EXTERN_C struct ZigClangQualType ZigClangASTContext_getPointerType(const struct ZigClangASTContext*, struct ZigClangQualType T); + +ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *); +ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *); +ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, + bool (*Fn)(void *context, const struct ZigClangDecl *decl)); + +ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordType_getDecl(const struct ZigClangRecordType *record_ty); +ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struct ZigClangEnumType *record_ty); + +ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl); +ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *); +ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *); + +ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *); +ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *); + +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangRecordDecl_getLocation(const struct ZigClangRecordDecl *); +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangEnumDecl_getLocation(const struct ZigClangEnumDecl *); +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangTypedefNameDecl_getLocation(const struct ZigClangTypedefNameDecl *); + +ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl); +ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl); +ZIG_EXTERN_C bool ZigClangRecordDecl_isAnonymousStructOrUnion(const struct ZigClangRecordDecl *record_decl); + +ZIG_EXTERN_C struct ZigClangQualType ZigClangEnumDecl_getIntegerType(const struct ZigClangEnumDecl *); + +ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangDecl *decl); + +ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b); + +ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *); +ZIG_EXTERN_C struct ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(const struct ZigClangTypedefNameDecl *); + +ZIG_EXTERN_C struct ZigClangQualType ZigClangQualType_getCanonicalType(struct ZigClangQualType); +ZIG_EXTERN_C const struct ZigClangType *ZigClangQualType_getTypePtr(struct ZigClangQualType); +ZIG_EXTERN_C void ZigClangQualType_addConst(struct ZigClangQualType *); +ZIG_EXTERN_C bool ZigClangQualType_eq(struct ZigClangQualType, struct ZigClangQualType); +ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(struct ZigClangQualType); +ZIG_EXTERN_C bool ZigClangQualType_isVolatileQualified(struct ZigClangQualType); +ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType); + +ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self); +ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self); +ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self); + +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangStmt_getBeginLoc(const struct ZigClangStmt *self); +ZIG_EXTERN_C enum ZigClangStmtClass ZigClangStmt_getStmtClass(const struct ZigClangStmt *self); +ZIG_EXTERN_C bool ZigClangStmt_classof_Expr(const struct ZigClangStmt *self); + +ZIG_EXTERN_C enum ZigClangStmtClass ZigClangExpr_getStmtClass(const struct ZigClangExpr *self); +ZIG_EXTERN_C struct ZigClangQualType ZigClangExpr_getType(const struct ZigClangExpr *self); +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangExpr_getBeginLoc(const struct ZigClangExpr *self); + +ZIG_EXTERN_C enum ZigClangAPValueKind ZigClangAPValue_getKind(const struct ZigClangAPValue *self); +ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPValue_getInt(const struct ZigClangAPValue *self); +ZIG_EXTERN_C unsigned ZigClangAPValue_getArrayInitializedElts(const struct ZigClangAPValue *self); +ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangAPValue_getArrayInitializedElt(const struct ZigClangAPValue *self, unsigned i); +ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangAPValue_getArrayFiller(const struct ZigClangAPValue *self); +ZIG_EXTERN_C unsigned ZigClangAPValue_getArraySize(const struct ZigClangAPValue *self); +ZIG_EXTERN_C struct ZigClangAPValueLValueBase ZigClangAPValue_getLValueBase(const struct ZigClangAPValue *self); + +ZIG_EXTERN_C bool ZigClangAPSInt_isSigned(const struct ZigClangAPSInt *self); +ZIG_EXTERN_C bool ZigClangAPSInt_isNegative(const struct ZigClangAPSInt *self); +ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPSInt_negate(const struct ZigClangAPSInt *self); +ZIG_EXTERN_C void ZigClangAPSInt_free(const struct ZigClangAPSInt *self); +ZIG_EXTERN_C const uint64_t *ZigClangAPSInt_getRawData(const struct ZigClangAPSInt *self); +ZIG_EXTERN_C unsigned ZigClangAPSInt_getNumWords(const struct ZigClangAPSInt *self); + +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAPValueLValueBase_dyn_cast_Expr(struct ZigClangAPValueLValueBase self); #endif diff --git a/std/c.zig b/std/c.zig index acff9229d1..ecbc55890a 100644 --- a/std/c.zig +++ b/std/c.zig @@ -12,6 +12,10 @@ pub use switch (builtin.os) { // TODO https://github.com/ziglang/zig/issues/265 on this whole file +pub const FILE = @OpaqueType(); +pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize; +pub extern "c" fn fread(ptr: [*]u8, size_of_type: usize, item_count: usize, stream: *FILE) usize; + pub extern "c" fn abort() noreturn; pub extern "c" fn exit(code: c_int) noreturn; pub extern "c" fn isatty(fd: c_int) c_int; diff --git a/std/io.zig b/std/io.zig index afbd8198fd..5ad35c91fb 100644 --- a/std/io.zig +++ b/std/io.zig @@ -36,6 +36,7 @@ pub fn getStdIn() GetStdIoErrs!File { } pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream; +pub const COutStream = @import("io/c_out_stream.zig").COutStream; pub fn InStream(comptime ReadError: type) type { return struct { @@ -1089,8 +1090,10 @@ test "io.readLineSliceFrom" { } pub const Packing = enum { - Byte, /// Pack data to byte alignment - Bit, /// Pack data to bit alignment + /// Pack data to byte alignment + Byte, + /// Pack data to bit alignment + Bit, }; /// Creates a deserializer that deserializes types from any stream. @@ -1111,10 +1114,12 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing, pub const Stream = InStream(Error); pub fn init(in_stream: *Stream) Self { - return Self{ .in_stream = switch (packing) { - .Bit => BitInStream(endian, Stream.Error).init(in_stream), - .Byte => in_stream, - } }; + return Self{ + .in_stream = switch (packing) { + .Bit => BitInStream(endian, Stream.Error).init(in_stream), + .Byte => in_stream, + }, + }; } pub fn alignToByte(self: *Self) void { @@ -1281,7 +1286,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing, ptr.* = null; return; } - + ptr.* = OC(undefined); //make it non-null so the following .? is guaranteed safe const val_ptr = &ptr.*.?; try self.deserializeInto(val_ptr); @@ -1320,10 +1325,12 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co pub const Stream = OutStream(Error); pub fn init(out_stream: *Stream) Self { - return Self{ .out_stream = switch (packing) { - .Bit => BitOutStream(endian, Stream.Error).init(out_stream), - .Byte => out_stream, - } }; + return Self{ + .out_stream = switch (packing) { + .Bit => BitOutStream(endian, Stream.Error).init(out_stream), + .Byte => out_stream, + }, + }; } /// Flushes any unwritten bits to the stream @@ -1450,4 +1457,3 @@ test "import io tests" { _ = @import("io_test.zig"); } } - diff --git a/std/io/c_out_stream.zig b/std/io/c_out_stream.zig new file mode 100644 index 0000000000..398668979e --- /dev/null +++ b/std/io/c_out_stream.zig @@ -0,0 +1,44 @@ +const std = @import("../std.zig"); +const OutStream = std.io.OutStream; +const builtin = @import("builtin"); +const posix = std.os.posix; + +/// TODO make std.os.FILE use *FILE when linking libc and this just becomes +/// std.io.FileOutStream because std.os.File.write would do this when linking +/// libc. +pub const COutStream = struct { + pub const Error = std.os.File.WriteError; + pub const Stream = OutStream(Error); + + stream: Stream, + c_file: *std.c.FILE, + + pub fn init(c_file: *std.c.FILE) COutStream { + return COutStream{ + .c_file = c_file, + .stream = Stream{ .writeFn = writeFn }, + }; + } + + fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void { + const self = @fieldParentPtr(COutStream, "stream", out_stream); + const amt_written = std.c.fwrite(bytes.ptr, 1, bytes.len, self.c_file); + if (amt_written == bytes.len) return; + const errno = std.c._errno().*; + switch (errno) { + 0 => unreachable, + posix.EINVAL => unreachable, + posix.EFAULT => unreachable, + posix.EAGAIN => unreachable, // this is a blocking API + posix.EBADF => unreachable, // always a race condition + posix.EDESTADDRREQ => unreachable, // connect was never called + posix.EDQUOT => return error.DiskQuota, + posix.EFBIG => return error.FileTooBig, + posix.EIO => return error.InputOutput, + posix.ENOSPC => return error.NoSpaceLeft, + posix.EPERM => return error.AccessDenied, + posix.EPIPE => return error.BrokenPipe, + else => return std.os.unexpectedErrorPosix(@intCast(usize, errno)), + } + } +}; -- cgit v1.2.3 From 712274997e80a93bdfe204f2238c4cfaac72a5b8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 21 Apr 2019 19:37:39 -0400 Subject: translate-c: unify API for self-hosted and C++ translate-c See #1964 --- src-self-hosted/clang.zig | 17 ++++++ src-self-hosted/main.zig | 18 ++++++- src-self-hosted/stage1.zig | 35 ++++++------- src-self-hosted/translate_c.zig | 13 ++++- src/codegen.cpp | 49 +++++++++++------- src/ir.cpp | 19 ++++--- src/translate_c.cpp | 86 ++++-------------------------- src/translate_c.hpp | 6 ++- src/userland.cpp | 9 +++- src/userland.h | 46 +++++++++++++---- src/zig_clang.cpp | 112 ++++++++++++++++++++++++++++++++++++++++ src/zig_clang.h | 14 ++--- 12 files changed, 281 insertions(+), 143 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 6f7c7eb853..a9cf06f8a5 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -862,6 +862,7 @@ pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void; pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64; pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint; pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr; +pub extern fn ZigClangASTUnit_delete(arg0: ?*struct_ZigClangASTUnit) void; pub const ZigClangSourceLocation = struct_ZigClangSourceLocation; pub const ZigClangQualType = struct_ZigClangQualType; pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase; @@ -942,3 +943,19 @@ pub const ZigClangTypeClass = enum_ZigClangTypeClass; pub const ZigClangStmtClass = enum_ZigClangStmtClass; pub const ZigClangCK = enum_ZigClangCK; pub const ZigClangAPValueKind = enum_ZigClangAPValueKind; + +pub const Stage2ErrorMsg = extern struct { + filename_ptr: ?[*]const u8, + filename_len: usize, + msg_ptr: [*]const u8, + msg_len: usize, + // valid until the ASTUnit is freed + source: ?[*]const u8, + // 0 based + line: c_uint, + // 0 based + column: c_uint, + // byte offset into source + offset: c_uint, +}; +pub extern fn ZigClangErrorMsg_delete(ptr: [*c]Stage2ErrorMsg, len: usize) void; diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 361afc80e3..759a84cb34 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -858,7 +858,23 @@ fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void { try stdout.write(usage); } -const info_zen = @import("stage1.zig").info_zen; +pub const info_zen = + \\ + \\ * Communicate intent precisely. + \\ * Edge cases matter. + \\ * Favor reading code over writing code. + \\ * Only one obvious way to do things. + \\ * Runtime crashes are better than bugs. + \\ * Compile errors are better than runtime crashes. + \\ * Incremental improvements. + \\ * Avoid local maximums. + \\ * Reduce the amount one must remember. + \\ * Minimize energy spent on coding style. + \\ * Together we serve end users. + \\ + \\ +; + fn cmdZen(allocator: *Allocator, args: []const []const u8) !void { try stdout.write(info_zen); } diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig index cf5f06c285..53bc1eeb69 100644 --- a/src-self-hosted/stage1.zig +++ b/src-self-hosted/stage1.zig @@ -3,37 +3,25 @@ const std = @import("std"); -pub const info_zen = - \\ - \\ * Communicate intent precisely. - \\ * Edge cases matter. - \\ * Favor reading code over writing code. - \\ * Only one obvious way to do things. - \\ * Runtime crashes are better than bugs. - \\ * Compile errors are better than runtime crashes. - \\ * Incremental improvements. - \\ * Avoid local maximums. - \\ * Reduce the amount one must remember. - \\ * Minimize energy spent on coding style. - \\ * Together we serve end users. - \\ - \\ -; - +// ABI warning export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { + const info_zen = @import("main.zig").info_zen; ptr.* = &info_zen; len.* = info_zen.len; } +// ABI warning export fn stage2_panic(ptr: [*]const u8, len: usize) void { @panic(ptr[0..len]); } +// ABI warning const TranslateMode = extern enum { import, translate, }; +// ABI warning const Error = extern enum { None, OutOfMemory, @@ -84,24 +72,33 @@ const Error = extern enum { const FILE = std.c.FILE; const ast = std.zig.ast; +const translate_c = @import("translate_c.zig"); /// Args should have a null terminating last arg. export fn stage2_translate_c( out_ast: **ast.Tree, + out_errors_ptr: *[*]translate_c.ClangErrMsg, + out_errors_len: *usize, args_begin: [*]?[*]const u8, args_end: [*]?[*]const u8, mode: TranslateMode, + resources_path: [*]const u8, ) Error { - const translate_c = @import("translate_c.zig"); + var errors: []translate_c.ClangErrMsg = undefined; out_ast.* = translate_c.translate(args_begin, args_end, switch (mode) { .import => translate_c.Mode.import, .translate => translate_c.Mode.translate, - }) catch |err| switch (err) { + }, &errors) catch |err| switch (err) { error.Unimplemented => return Error.Unimplemented, }; + return Error.None; } +export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void { + translate_c.freeErrors(errors_ptr[0..errors_len]); +} + export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error { const c_out_stream = &std.io.COutStream.init(output_file).stream; _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) { diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index c2d943b1ff..b2dcfffeb3 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -10,6 +10,17 @@ pub const Mode = enum { translate, }; -pub fn translate(args_begin: [*]?[*]const u8, args_end: [*]?[*]const u8, mode: Mode) !*ast.Tree { +pub const ClangErrMsg = Stage2ErrorMsg; + +pub fn translate( + args_begin: [*]?[*]const u8, + args_end: [*]?[*]const u8, + mode: Mode, + errors: *[]ClangErrMsg, +) !*ast.Tree { return error.Unimplemented; } + +pub fn freeErrors(errors: []ClangErrMsg) void { + ZigClangErrorMsg_delete(errors.ptr, errors.len); +} diff --git a/src/codegen.cpp b/src/codegen.cpp index b4ea0a9a96..27e2195a3c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8298,31 +8298,42 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us 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; + AstNode *root_node; + if (use_userland_implementation) { - Stage2Ast *ast; - if ((err = stage2_translate_c(&ast, &clang_argv.at(0), &clang_argv.last(), trans_mode))) { - zig_panic("TODO"); - } - stage2_render_ast(ast, out_file); + err = stage2_translate_c(&ast, &errors_ptr, &errors_len, + &clang_argv.at(0), &clang_argv.last(), trans_mode, resources_path); } else { - ZigList errors = {0}; - AstNode *root_node; - - err = parse_h_file(g, &root_node, &clang_argv.at(0), &clang_argv.last(), trans_mode, &errors); + err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(), + trans_mode, resources_path); + } - if (err == ErrorCCompileErrors && errors.length > 0) { - for (size_t i = 0; i < errors.length; i += 1) { - ErrorMsg *err_msg = errors.at(i); - print_err_msg(err_msg, g->err_color); - } - exit(1); + 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) : buf_alloc(), + 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 (err) { + fprintf(stderr, "unable to parse C file: %s\n", err_str(err)); + exit(1); + } + + if (use_userland_implementation) { + stage2_render_ast(ast, out_file); + } else { ast_render(out_file, root_node, 4); } } diff --git a/src/ir.cpp b/src/ir.cpp index 105dd0c3d6..3f74741995 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19103,25 +19103,32 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct clang_argv.append(nullptr); // to make the [start...end] argument work - ZigList errors = {0}; AstNode *root_node; + Stage2ErrorMsg *errors_ptr; + size_t errors_len; - if ((err = parse_h_file(ira->codegen, &root_node, &clang_argv.at(0), &clang_argv.last(), - Stage2TranslateModeImport, &errors))) + const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); + + if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len, + &clang_argv.at(0), &clang_argv.last(), Stage2TranslateModeImport, resources_path))) { if (err != ErrorCCompileErrors) { ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); return ira->codegen->invalid_instruction; } - assert(errors.length > 0); ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); if (ira->codegen->libc_link_lib == nullptr) { add_error_note(ira->codegen, parent_err_msg, node, buf_sprintf("libc headers not available; compilation does not link against libc")); } - for (size_t i = 0; i < errors.length; i += 1) { - ErrorMsg *err_msg = errors.at(i); + 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) : buf_alloc(), + clang_err->line, clang_err->column, clang_err->offset, clang_err->source, + buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); err_msg_add_note(parent_err_msg, err_msg); } diff --git a/src/translate_c.cpp b/src/translate_c.cpp index d19083ce73..1c8d8e51b3 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -76,10 +76,9 @@ struct TransScopeWhile { }; struct Context { - ZigList *errors; + AstNode *root; VisibMod visib_mod; bool want_export; - AstNode *root; HashMap decl_table; HashMap macro_table; HashMap global_table; @@ -5018,13 +5017,14 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) { } } -Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_begin, const char **args_end, - Stage2TranslateMode mode, ZigList *errors) +Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, + Stage2ErrorMsg **errors_ptr, size_t *errors_len, + const char **args_begin, const char **args_end, + Stage2TranslateMode mode, const char *resources_path) { Context context = {0}; Context *c = &context; c->warnings_on = codegen->verbose_cimport; - c->errors = errors; if (mode == Stage2TranslateModeImport) { c->visib_mod = VisibModPub; c->want_export = false; @@ -5039,78 +5039,10 @@ Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_ c->codegen = codegen; c->global_scope = trans_scope_root_create(c); - - clang::IntrusiveRefCntPtr diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions)); - - std::shared_ptr pch_container_ops = std::make_shared(); - - bool only_local_decls = true; - bool capture_diagnostics = true; - bool user_files_are_volatile = true; - bool allow_pch_with_compiler_errors = false; - bool single_file_parse = false; - bool for_serialization = false; - const char *resources_path = buf_ptr(codegen->zig_c_headers_dir); - std::unique_ptr err_unit; - ZigClangASTUnit *ast_unit = reinterpret_cast(clang::ASTUnit::LoadFromCommandLine( - args_begin, args_end, - pch_container_ops, diags, resources_path, - only_local_decls, capture_diagnostics, clang::None, true, 0, clang::TU_Complete, - false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None, - single_file_parse, user_files_are_volatile, for_serialization, clang::None, &err_unit, - nullptr)); - - // Early failures in LoadFromCommandLine may return with ErrUnit unset. - if (!ast_unit && !err_unit) { - return ErrorFileSystem; - } - - if (diags->getClient()->getNumErrors() > 0) { - if (ast_unit) { - err_unit = std::unique_ptr(reinterpret_cast(ast_unit)); - } - - for (clang::ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(), - it_end = err_unit->stored_diag_end(); - it != it_end; ++it) - { - switch (it->getLevel()) { - case clang::DiagnosticsEngine::Ignored: - case clang::DiagnosticsEngine::Note: - case clang::DiagnosticsEngine::Remark: - case clang::DiagnosticsEngine::Warning: - continue; - case clang::DiagnosticsEngine::Error: - case clang::DiagnosticsEngine::Fatal: - break; - } - llvm::StringRef msg_str_ref = it->getMessage(); - Buf *msg = string_ref_to_buf(msg_str_ref); - clang::FullSourceLoc fsl = it->getLocation(); - if (fsl.hasManager()) { - clang::FileID file_id = fsl.getFileID(); - clang::StringRef filename = fsl.getManager().getFilename(fsl); - unsigned line = fsl.getSpellingLineNumber() - 1; - unsigned column = fsl.getSpellingColumnNumber() - 1; - unsigned offset = fsl.getManager().getFileOffset(fsl); - const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin(); - Buf *path; - if (filename.empty()) { - path = buf_alloc(); - } else { - path = string_ref_to_buf(filename); - } - - ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg); - - c->errors->append(err_msg); - } else { - // NOTE the only known way this gets triggered right now is if you have a lot of errors - // clang emits "too many errors emitted, stopping now" - fprintf(stderr, "unexpected error from clang: %s\n", buf_ptr(msg)); - } - } - + ZigClangASTUnit *ast_unit = ZigClangLoadFromCommandLine(args_begin, args_end, errors_ptr, errors_len, + resources_path); + if (ast_unit == nullptr) { + if (*errors_len == 0) return ErrorNoMem; return ErrorCCompileErrors; } diff --git a/src/translate_c.hpp b/src/translate_c.hpp index b6e4b6bcbb..4eac26ddb5 100644 --- a/src/translate_c.hpp +++ b/src/translate_c.hpp @@ -11,7 +11,9 @@ #include "all_types.hpp" -Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_begin, const char **args_end, - Stage2TranslateMode mode, ZigList *errors); +Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, + Stage2ErrorMsg **errors_ptr, size_t *errors_len, + const char **args_begin, const char **args_end, + Stage2TranslateMode mode, const char *resources_path); #endif diff --git a/src/userland.cpp b/src/userland.cpp index 9935d5c04a..fad1450f0d 100644 --- a/src/userland.cpp +++ b/src/userland.cpp @@ -8,12 +8,19 @@ #include Error stage2_translate_c(struct Stage2Ast **out_ast, - const char **args_begin, const char **args_end, enum Stage2TranslateMode mode) + struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len, + const char **args_begin, const char **args_end, enum Stage2TranslateMode mode, + const char *resources_path) { const char *msg = "stage0 called stage2_translate_c"; stage2_panic(msg, strlen(msg)); } +void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len) { + const char *msg = "stage0 called stage2_free_clang_errors"; + stage2_panic(msg, strlen(msg)); +} + void stage2_zen(const char **ptr, size_t *len) { const char *msg = "stage0 called stage2_zen"; stage2_panic(msg, strlen(msg)); diff --git a/src/userland.h b/src/userland.h index 35fd46942b..ba797d8b25 100644 --- a/src/userland.h +++ b/src/userland.h @@ -12,20 +12,21 @@ #include #ifdef __cplusplus -#define ZIG_USERLAND_EXTERN_C extern "C" +#define ZIG_EXTERN_C extern "C" #else -#define ZIG_USERLAND_EXTERN_C +#define ZIG_EXTERN_C #endif #if defined(_MSC_VER) -#define ZIG_USERLAND_ATTRIBUTE_NORETURN __declspec(noreturn) +#define ZIG_ATTRIBUTE_NORETURN __declspec(noreturn) #else -#define ZIG_USERLAND_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#define ZIG_ATTRIBUTE_NORETURN __attribute__((noreturn)) #endif -// The types and declarations in this file must match both those in userland.cpp and -// src-self-hosted/stage1.zig. +// ABI warning: the types and declarations in this file must match both those in +// userland.cpp and src-self-hosted/stage1.zig. +// ABI warning enum Error { ErrorNone, ErrorNoMem, @@ -74,20 +75,43 @@ enum Error { ErrorNoSpaceLeft, }; +// ABI warning enum Stage2TranslateMode { Stage2TranslateModeImport, Stage2TranslateModeTranslate, }; +// ABI warning +struct Stage2ErrorMsg { + const char *filename_ptr; // can be null + size_t filename_len; + const char *msg_ptr; + size_t msg_len; + const char *source; // valid until the ASTUnit is freed. can be null + unsigned line; // 0 based + unsigned column; // 0 based + unsigned offset; // byte offset into source +}; + +// ABI warning struct Stage2Ast; -ZIG_USERLAND_EXTERN_C Error stage2_translate_c(struct Stage2Ast **out_ast, - const char **args_begin, const char **args_end, enum Stage2TranslateMode mode); +// ABI warning +ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast, + struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len, + const char **args_begin, const char **args_end, enum Stage2TranslateMode mode, + const char *resources_path); + +// ABI warning +ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len); -ZIG_USERLAND_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file); +// ABI warning +ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file); -ZIG_USERLAND_EXTERN_C void stage2_zen(const char **ptr, size_t *len); +// ABI warning +ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len); -ZIG_USERLAND_EXTERN_C ZIG_USERLAND_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); +// ABI warning +ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); #endif diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 6142c808ad..cc79941190 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1147,3 +1147,115 @@ ZigClangAPValueLValueBase ZigClangAPValue_getLValueBase(const ZigClangAPValue *s clang::APValue::LValueBase lval_base = casted->getLValueBase(); return bitcast(lval_base); } + +ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end, + struct Stage2ErrorMsg **errors_ptr, size_t *errors_len, const char *resources_path) +{ + clang::IntrusiveRefCntPtr diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions)); + + std::shared_ptr pch_container_ops = std::make_shared(); + + bool only_local_decls = true; + bool capture_diagnostics = true; + bool user_files_are_volatile = true; + bool allow_pch_with_compiler_errors = false; + bool single_file_parse = false; + bool for_serialization = false; + std::unique_ptr *err_unit = new std::unique_ptr(); + clang::ASTUnit *ast_unit = clang::ASTUnit::LoadFromCommandLine( + args_begin, args_end, + pch_container_ops, diags, resources_path, + only_local_decls, capture_diagnostics, clang::None, true, 0, clang::TU_Complete, + false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None, + single_file_parse, user_files_are_volatile, for_serialization, clang::None, err_unit, + nullptr); + + // Early failures in LoadFromCommandLine may return with ErrUnit unset. + if (!ast_unit && !err_unit) { + return nullptr; + } + + if (diags->getClient()->getNumErrors() > 0) { + if (ast_unit) { + *err_unit = std::unique_ptr(ast_unit); + } + + size_t cap = 4; + *errors_len = 0; + *errors_ptr = reinterpret_cast(malloc(cap * sizeof(Stage2ErrorMsg))); + if (*errors_ptr == nullptr) { + return nullptr; + } + + for (clang::ASTUnit::stored_diag_iterator it = (*err_unit)->stored_diag_begin(), + it_end = (*err_unit)->stored_diag_end(); + it != it_end; ++it) + { + switch (it->getLevel()) { + case clang::DiagnosticsEngine::Ignored: + case clang::DiagnosticsEngine::Note: + case clang::DiagnosticsEngine::Remark: + case clang::DiagnosticsEngine::Warning: + continue; + case clang::DiagnosticsEngine::Error: + case clang::DiagnosticsEngine::Fatal: + break; + } + llvm::StringRef msg_str_ref = it->getMessage(); + if (*errors_len >= cap) { + cap *= 2; + Stage2ErrorMsg *new_errors = reinterpret_cast( + realloc(*errors_ptr, cap * sizeof(Stage2ErrorMsg))); + if (new_errors == nullptr) { + free(*errors_ptr); + *errors_ptr = nullptr; + *errors_len = 0; + return nullptr; + } + *errors_ptr = new_errors; + } + Stage2ErrorMsg *msg = *errors_ptr + *errors_len; + *errors_len += 1; + msg->msg_ptr = (const char *)msg_str_ref.bytes_begin(); + msg->msg_len = msg_str_ref.size(); + + clang::FullSourceLoc fsl = it->getLocation(); + if (fsl.hasManager()) { + clang::FileID file_id = fsl.getFileID(); + clang::StringRef filename = fsl.getManager().getFilename(fsl); + if (filename.empty()) { + msg->filename_ptr = nullptr; + } else { + msg->filename_ptr = (const char *)filename.bytes_begin(); + msg->filename_len = filename.size(); + } + msg->source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin(); + msg->line = fsl.getSpellingLineNumber() - 1; + msg->column = fsl.getSpellingColumnNumber() - 1; + msg->offset = fsl.getManager().getFileOffset(fsl); + } else { + // The only known way this gets triggered right now is if you have a lot of errors + // clang emits "too many errors emitted, stopping now" + msg->filename_ptr = nullptr; + msg->source = nullptr; + } + } + + if (*errors_len == 0) { + free(*errors_ptr); + *errors_ptr = nullptr; + } + + return nullptr; + } + + return reinterpret_cast(ast_unit); +} + +void ZigClangErrorMsg_delete(Stage2ErrorMsg *ptr, size_t len) { + free(ptr); +} + +void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) { + delete reinterpret_cast(self); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 148ee34f51..f237449527 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -8,15 +8,10 @@ #ifndef ZIG_ZIG_CLANG_H #define ZIG_ZIG_CLANG_H +#include "userland.h" #include #include -#ifdef __cplusplus -#define ZIG_EXTERN_C extern "C" -#else -#define ZIG_EXTERN_C -#endif - // ATTENTION: If you modify this file, be sure to update the corresponding // extern function declarations in the self-hosted compiler file // src-self-hosted/clang.zig. @@ -500,6 +495,13 @@ ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const struct Zig ZIG_EXTERN_C struct ZigClangQualType ZigClangASTContext_getPointerType(const struct ZigClangASTContext*, struct ZigClangQualType T); + +// Can return null. +ZIG_EXTERN_C struct ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end, + struct Stage2ErrorMsg **errors_ptr, size_t *errors_len, const char *resources_path); +ZIG_EXTERN_C void ZigClangASTUnit_delete(struct ZigClangASTUnit *); +ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len); + ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *); ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *); ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, -- cgit v1.2.3 From e1bf74fca3de7943b8f7c15be4da3dbc8e3da17e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 21 Apr 2019 20:19:48 -0400 Subject: translate-c: put -x c back in there, it's necessary --- src/codegen.cpp | 21 +++++++++++++-------- src/ir.cpp | 9 ++++++++- src/translate_c.cpp | 2 ++ 3 files changed, 23 insertions(+), 9 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 27e2195a3c..8d39c60ef7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8155,6 +8155,11 @@ static void detect_libc(CodeGen *g) { // does not add the "cc" arg void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c) { + if (translate_c) { + args.append("-x"); + args.append("c"); + } + if (out_dep_path != nullptr) { args.append("-MD"); args.append("-MV"); @@ -8166,13 +8171,6 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa args.append("-fno-spell-checking"); if (translate_c) { - // TODO these args shouldn't be special from the non-translate-c args, probably. - args.append("-nobuiltininc"); - args.append("-nostdinc++"); - if (g->libc_link_lib == nullptr) { - args.append("-nolibc"); - } - // this gives us access to preprocessing entities, presumably at // the cost of performance args.append("-Xclang"); @@ -8293,9 +8291,16 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us ZigList clang_argv = {0}; add_cc_args(g, clang_argv, nullptr, true); - clang_argv.append("-c"); 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); diff --git a/src/ir.cpp b/src/ir.cpp index 3f74741995..a2bd72b197 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19098,9 +19098,16 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true); - clang_argv.append("-c"); clang_argv.append(buf_ptr(&tmp_c_file_path)); + if (ira->codegen->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 AstNode *root_node; diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 1c8d8e51b3..f8e57098a6 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -5060,5 +5060,7 @@ Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, *out_root_node = c->root; + ZigClangASTUnit_delete(ast_unit); + return ErrorNone; } -- cgit v1.2.3 From 3552180143a86432bfec3e71ba2fdd7aaebb0549 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 3 May 2019 01:23:35 -0400 Subject: optimize `@memset` with `undefined` When using `@memset` to set bytes to `undefined`, Zig notices this case and does a single Valgrind client request rather than N. Speeds up all allocators in safe modes. Closes #2388 --- src/codegen.cpp | 47 +++++++++++++++++++++++++++++++---------------- std/mem.zig | 10 ++-------- 2 files changed, 33 insertions(+), 24 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 8d39c60ef7..9eeee1dee1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1036,7 +1036,7 @@ static LLVMValueRef get_write_register_fn_val(CodeGen *g) { // !0 = !{!"sp\00"} LLVMTypeRef param_types[] = { - LLVMMetadataTypeInContext(LLVMGetGlobalContext()), + LLVMMetadataTypeInContext(LLVMGetGlobalContext()), LLVMIntType(g->pointer_size_bytes * 8), }; @@ -3491,6 +3491,15 @@ static bool want_valgrind_support(CodeGen *g) { 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; + LLVMValueRef zero = LLVMConstInt(usize->llvm_type, 0, false); + LLVMValueRef req = LLVMConstInt(usize->llvm_type, VG_USERREQ__MAKE_MEM_UNDEFINED, false); + LLVMValueRef ptr_as_usize = LLVMBuildPtrToInt(g->builder, dest_ptr, usize->llvm_type, ""); + gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero); +} + static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) { assert(type_has_bits(value_type)); uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, value_type)); @@ -3505,11 +3514,7 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_ 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)) { - static const uint32_t VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; - LLVMValueRef zero = LLVMConstInt(usize->llvm_type, 0, false); - LLVMValueRef req = LLVMConstInt(usize->llvm_type, VG_USERREQ__MAKE_MEM_UNDEFINED, false); - LLVMValueRef ptr_as_usize = LLVMBuildPtrToInt(g->builder, dest_ptr, usize->llvm_type, ""); - gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero); + gen_valgrind_undef(g, dest_ptr, byte_count); } } @@ -3519,14 +3524,14 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir if (!type_has_bits(ptr_type)) return nullptr; - bool have_init_expr = !value_is_all_undef(&instruction->value->value); + bool have_init_expr = !value_is_all_undef(&instruction->value->value); if (have_init_expr) { LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); LLVMValueRef value = ir_llvm_value(g, instruction->value); gen_assign_raw(g, ptr, ptr_type, value); } else if (ir_want_runtime_safety(g, &instruction->base)) { gen_undef_init(g, get_ptr_align(g, ptr_type), instruction->value->value.type, - ir_llvm_value(g, instruction->ptr)); + ir_llvm_value(g, instruction->ptr)); } return nullptr; } @@ -3729,7 +3734,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr } FnWalk fn_walk = {}; fn_walk.id = FnWalkIdCall; - fn_walk.data.call.inst = instruction; + fn_walk.data.call.inst = instruction; fn_walk.data.call.is_var_args = is_var_args; fn_walk.data.call.gen_param_values = &gen_param_values; walk_function_params(g, fn_type, &fn_walk); @@ -3749,7 +3754,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr LLVMCallConv llvm_cc = get_llvm_cc(g, cc); LLVMValueRef result; - + if (instruction->new_stack == nullptr) { result = ZigLLVMBuildCall(g->builder, fn_val, gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, fn_inline, ""); @@ -4229,7 +4234,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { LLVMTypeRef tag_int_llvm_type = get_llvm_type(g, tag_int_type); LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMPointerType(get_llvm_type(g, u8_slice_type), 0), &tag_int_llvm_type, 1, false); - + Buf *fn_name = get_mangled_name(g, buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name)), false); LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref); LLVMSetLinkage(fn_val, LLVMInternalLinkage); @@ -4529,17 +4534,27 @@ static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrI static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrInstructionMemset *instruction) { LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr); - LLVMValueRef char_val = ir_llvm_value(g, instruction->byte); LLVMValueRef len_val = ir_llvm_value(g, instruction->count); LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); - LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); ZigType *ptr_type = instruction->dest_ptr->value.type; assert(ptr_type->id == ZigTypeIdPointer); - ZigLLVMBuildMemSet(g->builder, dest_ptr_casted, char_val, len_val, get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile); + bool val_is_undef = value_is_all_undef(&instruction->byte->value); + LLVMValueRef fill_char; + if (val_is_undef) { + fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false); + } else { + fill_char = ir_llvm_value(g, instruction->byte); + } + 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)) { + gen_valgrind_undef(g, dest_ptr_casted, len_val); + } return nullptr; } @@ -6944,7 +6959,7 @@ static void do_code_gen(CodeGen *g) { ir_render(g, fn_table_entry); } - + assert(!g->errors.length); if (buf_len(&g->global_asm) != 0) { @@ -7752,7 +7767,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { assert(ContainerLayoutAuto == 0); assert(ContainerLayoutExtern == 1); assert(ContainerLayoutPacked == 2); - + assert(CallingConventionUnspecified == 0); assert(CallingConventionC == 1); assert(CallingConventionCold == 2); diff --git a/std/mem.zig b/std/mem.zig index 46cfda2d94..2407b56f07 100644 --- a/std/mem.zig +++ b/std/mem.zig @@ -104,10 +104,7 @@ pub const Allocator = struct { const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory; const byte_slice = try self.reallocFn(self, ([*]u8)(undefined)[0..0], undefined, byte_count, alignment); assert(byte_slice.len == byte_count); - // This loop gets optimized out in ReleaseFast mode - for (byte_slice) |*byte| { - byte.* = undefined; - } + @memset(byte_slice.ptr, undefined, byte_slice.len); return @bytesToSlice(T, @alignCast(alignment, byte_slice)); } @@ -153,10 +150,7 @@ pub const Allocator = struct { const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment); assert(byte_slice.len == byte_count); if (new_n > old_mem.len) { - // This loop gets optimized out in ReleaseFast mode - for (byte_slice[old_byte_slice.len..]) |*byte| { - byte.* = undefined; - } + @memset(byte_slice.ptr + old_byte_slice.len, undefined, byte_slice.len - old_byte_slice.len); } return @bytesToSlice(T, @alignCast(new_alignment, byte_slice)); } -- cgit v1.2.3 From bd9c629c4c306c9159a5e6ad16fe5637d2bc6dbf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 3 May 2019 14:39:54 -0400 Subject: always respect threadlocal for variables with external linkage Previously if you had, for example: extern "c" threadlocal var errno: c_int; This would turn errno into a normal variable for --single-threaded builds. However for variables with external linkage, there is an ABI to uphold. This is needed to make errno work for DragonFly BSD. See #2381. --- src/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 9eeee1dee1..7dfdf71725 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6639,7 +6639,7 @@ static void validate_inline_fns(CodeGen *g) { } static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) { - if (var->is_thread_local && !g->is_single_threaded) { + if (var->is_thread_local && (!g->is_single_threaded || var->linkage != VarLinkageInternal)) { LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel); } } -- cgit v1.2.3 From be7cacfbbec8aed234a0316d11a9ae0e8cda0286 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 7 May 2019 00:49:49 +0200 Subject: Implement stack probes for x86/x86_64 Enabled on non-Windows systems only since it already requires stack probes. --- CMakeLists.txt | 1 + src/codegen.cpp | 11 ++ src/main.cpp | 6 + std/special/compiler_rt.zig | 125 +++---------------- std/special/compiler_rt/stack_probe.zig | 206 ++++++++++++++++++++++++++++++++ 5 files changed, 239 insertions(+), 110 deletions(-) create mode 100644 std/special/compiler_rt/stack_probe.zig (limited to 'src/codegen.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index c55ced8927..9bffaa4ce8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -644,6 +644,7 @@ set(ZIG_STD_FILES "special/build_runner.zig" "special/builtin.zig" "special/compiler_rt.zig" + "special/compiler_rt/stack_probe.zig" "special/compiler_rt/arm/aeabi_fcmp.zig" "special/compiler_rt/arm/aeabi_dcmp.zig" "special/compiler_rt/addXf3.zig" diff --git a/src/codegen.cpp b/src/codegen.cpp index 7dfdf71725..396dfb1f88 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -399,6 +399,15 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { } } +static void add_probe_stack_attr(CodeGen *g, LLVMValueRef fn_val) { + // Windows already emits its own stack probes + if (g->zig_target->os != OsWindows && + (g->zig_target->arch == ZigLLVM_x86 || + g->zig_target->arch == ZigLLVM_x86_64)) { + addLLVMFnAttrStr(fn_val, "probe-stack", "__zig_probe_stack"); + } +} + static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) { switch (id) { case GlobalLinkageIdInternal: @@ -587,6 +596,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong"); addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4"); } + + add_probe_stack_attr(g, fn_table_entry->llvm_value); } } else { maybe_import_dll(g, fn_table_entry->llvm_value, linkage); diff --git a/src/main.cpp b/src/main.cpp index 2915fd4b9d..6cd057fd40 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,6 +18,12 @@ #include +// Define this symbol here so that we can link with the zig objects during the +// compiler bootstrap phase +extern "C" { + void __zig_probe_stack(void) { } +} + static int print_error_usage(const char *arg0) { fprintf(stderr, "See `%s --help` for detailed usage information\n", arg0); return EXIT_FAILURE; diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index b24a84ac7d..2faec8eab7 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -1,10 +1,17 @@ const builtin = @import("builtin"); const is_test = builtin.is_test; +const stack_probe = @import("compiler_rt/stack_probe.zig"); + comptime { const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; + switch (builtin.arch) { + .i386, .x86_64 => @export("__zig_probe_stack", @import("compiler_rt/stack_probe.zig").zig_probe_stack, linkage), + else => { } + } + @export("__lesf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage); @export("__ledf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage); @export("__letf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage); @@ -191,20 +198,20 @@ comptime { @export("__aeabi_dcmpun", @import("compiler_rt/comparedf2.zig").__unorddf2, linkage); } if (builtin.os == builtin.Os.windows) { + if (!builtin.link_libc) { + @export("_chkstk", @import("compiler_rt/stack_probe.zig")._chkstk, strong_linkage); + @export("__chkstk", @import("compiler_rt/stack_probe.zig").__chkstk, strong_linkage); + @export("___chkstk", @import("compiler_rt/stack_probe.zig").___chkstk, strong_linkage); + @export("__chkstk_ms", @import("compiler_rt/stack_probe.zig").__chkstk_ms, strong_linkage); + @export("___chkstk_ms", @import("compiler_rt/stack_probe.zig").___chkstk_ms, strong_linkage); + } + switch (builtin.arch) { builtin.Arch.i386 => { - if (!builtin.link_libc) { - @export("_chkstk", _chkstk, strong_linkage); - @export("__chkstk_ms", __chkstk_ms, linkage); - } @export("_aulldiv", @import("compiler_rt/aulldiv.zig")._aulldiv, strong_linkage); @export("_aullrem", @import("compiler_rt/aullrem.zig")._aullrem, strong_linkage); }, builtin.Arch.x86_64 => { - if (!builtin.link_libc) { - @export("__chkstk", __chkstk, strong_linkage); - @export("___chkstk_ms", ___chkstk_ms, linkage); - } // The "ti" functions must use @Vector(2, u64) parameter types to adhere to the ABI // that LLVM expects compiler-rt to have. @export("__divti3", @import("compiler_rt/divti3.zig").__divti3_windows_x86_64, linkage); @@ -492,108 +499,6 @@ nakedcc fn __aeabi_memcmp() noreturn { unreachable; } -// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments, -// then decrement %esp by %eax. Preserves all registers except %esp and flags. -// This routine is windows specific -// http://msdn.microsoft.com/en-us/library/ms648426.aspx -nakedcc fn _chkstk() align(4) void { - @setRuntimeSafety(false); - - asm volatile ( - \\ push %%ecx - \\ push %%eax - \\ cmp $0x1000,%%eax - \\ lea 12(%%esp),%%ecx - \\ jb 1f - \\ 2: - \\ sub $0x1000,%%ecx - \\ test %%ecx,(%%ecx) - \\ sub $0x1000,%%eax - \\ cmp $0x1000,%%eax - \\ ja 2b - \\ 1: - \\ sub %%eax,%%ecx - \\ test %%ecx,(%%ecx) - \\ pop %%eax - \\ pop %%ecx - \\ ret - ); -} - -nakedcc fn __chkstk() align(4) void { - @setRuntimeSafety(false); - - asm volatile ( - \\ push %%rcx - \\ push %%rax - \\ cmp $0x1000,%%rax - \\ lea 24(%%rsp),%%rcx - \\ jb 1f - \\2: - \\ sub $0x1000,%%rcx - \\ test %%rcx,(%%rcx) - \\ sub $0x1000,%%rax - \\ cmp $0x1000,%%rax - \\ ja 2b - \\1: - \\ sub %%rax,%%rcx - \\ test %%rcx,(%%rcx) - \\ pop %%rax - \\ pop %%rcx - \\ ret - ); -} - -// _chkstk routine -// This routine is windows specific -// http://msdn.microsoft.com/en-us/library/ms648426.aspx -nakedcc fn __chkstk_ms() align(4) void { - @setRuntimeSafety(false); - - asm volatile ( - \\ push %%ecx - \\ push %%eax - \\ cmp $0x1000,%%eax - \\ lea 12(%%esp),%%ecx - \\ jb 1f - \\ 2: - \\ sub $0x1000,%%ecx - \\ test %%ecx,(%%ecx) - \\ sub $0x1000,%%eax - \\ cmp $0x1000,%%eax - \\ ja 2b - \\ 1: - \\ sub %%eax,%%ecx - \\ test %%ecx,(%%ecx) - \\ pop %%eax - \\ pop %%ecx - \\ ret - ); -} - -nakedcc fn ___chkstk_ms() align(4) void { - @setRuntimeSafety(false); - - asm volatile ( - \\ push %%rcx - \\ push %%rax - \\ cmp $0x1000,%%rax - \\ lea 24(%%rsp),%%rcx - \\ jb 1f - \\2: - \\ sub $0x1000,%%rcx - \\ test %%rcx,(%%rcx) - \\ sub $0x1000,%%rax - \\ cmp $0x1000,%%rax - \\ ja 2b - \\1: - \\ sub %%rax,%%rcx - \\ test %%rcx,(%%rcx) - \\ pop %%rax - \\ pop %%rcx - \\ ret - ); -} extern fn __divmodsi4(a: i32, b: i32, rem: *i32) i32 { @setRuntimeSafety(is_test); diff --git a/std/special/compiler_rt/stack_probe.zig b/std/special/compiler_rt/stack_probe.zig new file mode 100644 index 0000000000..71a349d2a8 --- /dev/null +++ b/std/special/compiler_rt/stack_probe.zig @@ -0,0 +1,206 @@ +const builtin = @import("builtin"); + +// Zig's own stack-probe routine (available only on x86 and x86_64) +pub nakedcc fn zig_probe_stack() void { + @setRuntimeSafety(false); + + // Versions of the Linux kernel before 5.1 treat any access below SP as + // invalid so let's update it on the go, otherwise we'll get a segfault + // instead of triggering the stack growth. + + switch (builtin.arch) { + .x86_64 => { + // %rax = probe length, %rsp = stack pointer + asm volatile ( + \\ push %%rcx + \\ mov %%rax, %%rcx + \\ cmp $0x1000,%%rcx + \\ jb 2f + \\ 1: + \\ sub $0x1000,%%rsp + \\ orl $0,16(%%rsp) + \\ sub $0x1000,%%rcx + \\ cmp $0x1000,%%rcx + \\ ja 1b + \\ 2: + \\ sub %%rcx, %%rsp + \\ orl $0,16(%%rsp) + \\ add %%rax,%%rsp + \\ pop %%rcx + \\ ret + ); + }, + .i386 => { + // %eax = probe length, %esp = stack pointer + asm volatile ( + \\ push %%ecx + \\ mov %%eax, %%ecx + \\ cmp $0x1000,%%ecx + \\ jb 2f + \\ 1: + \\ sub $0x1000,%%esp + \\ orl $0,8(%%esp) + \\ sub $0x1000,%%ecx + \\ cmp $0x1000,%%ecx + \\ ja 1b + \\ 2: + \\ sub %%ecx, %%esp + \\ orl $0,8(%%esp) + \\ add %%eax,%%esp + \\ pop %%ecx + \\ ret + ); + }, + else => { } + } + + unreachable; +} + +fn win_probe_stack_only() void { + @setRuntimeSafety(false); + + switch (builtin.arch) { + .x86_64 => { + asm volatile ( + \\ push %%rcx + \\ push %%rax + \\ cmp $0x1000,%%rax + \\ lea 24(%%rsp),%%rcx + \\ jb 1f + \\ 2: + \\ sub $0x1000,%%rcx + \\ test %%rcx,(%%rcx) + \\ sub $0x1000,%%rax + \\ cmp $0x1000,%%rax + \\ ja 2b + \\ 1: + \\ sub %%rax,%%rcx + \\ test %%rcx,(%%rcx) + \\ pop %%rax + \\ pop %%rcx + \\ ret + ); + }, + .i386 => { + asm volatile ( + \\ push %%ecx + \\ push %%eax + \\ cmp $0x1000,%%eax + \\ lea 12(%%esp),%%ecx + \\ jb 1f + \\ 2: + \\ sub $0x1000,%%ecx + \\ test %%ecx,(%%ecx) + \\ sub $0x1000,%%eax + \\ cmp $0x1000,%%eax + \\ ja 2b + \\ 1: + \\ sub %%eax,%%ecx + \\ test %%ecx,(%%ecx) + \\ pop %%eax + \\ pop %%ecx + \\ ret + ); + }, + else => { } + } + + unreachable; +} + +fn win_probe_stack_adjust_sp() void { + @setRuntimeSafety(false); + + switch (builtin.arch) { + .x86_64 => { + asm volatile ( + \\ push %%rcx + \\ cmp $0x1000,%%rax + \\ lea 16(%%rsp),%%rcx + \\ jb 1f + \\ 2: + \\ sub $0x1000,%%rcx + \\ test %%rcx,(%%rcx) + \\ sub $0x1000,%%rax + \\ cmp $0x1000,%%rax + \\ ja 2b + \\ 1: + \\ sub %%rax,%%rcx + \\ test %%rcx,(%%rcx) + \\ + \\ lea 8(%%rsp),%%rax + \\ mov %%rcx,%%rsp + \\ mov -8(%%rax),%%rcx + \\ push (%%rax) + \\ sub %%rsp,%%rax + \\ ret + ); + }, + .i386 => { + asm volatile ( + \\ push %%ecx + \\ cmp $0x1000,%%eax + \\ lea 8(%%esp),%%ecx + \\ jb 1f + \\ 2: + \\ sub $0x1000,%%ecx + \\ test %%ecx,(%%ecx) + \\ sub $0x1000,%%eax + \\ cmp $0x1000,%%eax + \\ ja 2b + \\ 1: + \\ sub %%eax,%%ecx + \\ test %%ecx,(%%ecx) + \\ + \\ lea 4(%%esp),%%eax + \\ mov %%ecx,%%esp + \\ mov -4(%%eax),%%ecx + \\ push (%%eax) + \\ sub %%esp,%%eax + \\ ret + ); + }, + else => { }, + } + + unreachable; +} + +// Windows has a multitude of stack-probing functions with similar names and +// slightly different behaviours: some behave as alloca() and update the stack +// pointer after probing the stack, other do not. +// +// Function name | Adjusts the SP? | +// | x86 | x86_64 | +// ---------------------------------------- +// _chkstk (_alloca) | yes | yes | +// __chkstk | yes | no | +// __chkstk_ms | no | no | +// ___chkstk (__alloca) | yes | yes | +// ___chkstk_ms | no | no | + +pub nakedcc fn _chkstk() void { + @setRuntimeSafety(false); + @inlineCall(win_probe_stack_adjust_sp); +} +pub nakedcc fn __chkstk() void { + @setRuntimeSafety(false); + switch (builtin.arch) { + .i386 => @inlineCall(win_probe_stack_adjust_sp), + .x86_64 => @inlineCall(win_probe_stack_only), + else => unreachable + } +} +pub nakedcc fn ___chkstk() void { + @setRuntimeSafety(false); + @inlineCall(win_probe_stack_adjust_sp); +} +pub nakedcc fn __chkstk_ms() void { + @setRuntimeSafety(false); + @inlineCall(win_probe_stack_only); +} +pub nakedcc fn ___chkstk_ms() void { + @setRuntimeSafety(false); + @inlineCall(win_probe_stack_only); +} -- cgit v1.2.3 From 50bbb34594eedf7a978c00edb525bcea472b554b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 8 May 2019 16:06:34 -0400 Subject: C pointers support `null` See #1967 --- src/codegen.cpp | 22 ++++----- src/ir.cpp | 97 ++++++++++++++++++++++++++++++++------- test/compile_errors.zig | 2 +- test/stage1/behavior/pointers.zig | 28 +++++++++++ 4 files changed, 121 insertions(+), 28 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 396dfb1f88..712ee908cb 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4023,19 +4023,19 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru } static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueRef maybe_handle) { - assert(maybe_type->id == ZigTypeIdOptional); + assert(maybe_type->id == ZigTypeIdOptional || + (maybe_type->id == ZigTypeIdPointer && maybe_type->data.pointer.allow_zero)); + ZigType *child_type = maybe_type->data.maybe.child_type; - if (!type_has_bits(child_type)) { + if (!type_has_bits(child_type)) return maybe_handle; - } else { - bool is_scalar = !handle_is_ptr(maybe_type); - if (is_scalar) { - return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), ""); - } else { - LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, ""); - return gen_load_untyped(g, maybe_field_ptr, 0, false, ""); - } - } + + bool is_scalar = !handle_is_ptr(maybe_type); + if (is_scalar) + return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), ""); + + LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, ""); + return gen_load_untyped(g, maybe_field_ptr, 0, false, ""); } static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable, diff --git a/src/ir.cpp b/src/ir.cpp index 91f931462e..1b0fbd1f7f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10283,6 +10283,12 @@ static IrInstruction *ir_const_bool(IrAnalyze *ira, IrInstruction *source_instru return result; } +static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { + IrInstruction *result = ir_const(ira, source_instruction, ty); + result->value.special = ConstValSpecialUndef; + return result; +} + static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); } @@ -10596,19 +10602,34 @@ static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *so assert(instr_is_comptime(value)); ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); - assert(val); + assert(val != nullptr); - IrInstructionConst *const_instruction = ir_create_instruction(&ira->new_irb, source_instr->scope, source_instr->source_node); - const_instruction->base.value.special = ConstValSpecialStatic; + IrInstruction *result = ir_const(ira, source_instr, wanted_type); + result->value.special = ConstValSpecialStatic; if (get_codegen_ptr_type(wanted_type) != nullptr) { - const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialNull; + result->value.data.x_ptr.special = ConstPtrSpecialNull; } else if (is_opt_err_set(wanted_type)) { - const_instruction->base.value.data.x_err_set = nullptr; + result->value.data.x_err_set = nullptr; } else { - const_instruction->base.value.data.x_optional = nullptr; + result->value.data.x_optional = nullptr; } - const_instruction->base.value.type = wanted_type; - return &const_instruction->base; + return result; +} + +static IrInstruction *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *value, ZigType *wanted_type) +{ + assert(wanted_type->id == ZigTypeIdPointer); + assert(wanted_type->data.pointer.ptr_len == PtrLenC); + assert(instr_is_comptime(value)); + + ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); + assert(val != nullptr); + + IrInstruction *result = ir_const(ira, source_instr, wanted_type); + result->value.data.x_ptr.special = ConstPtrSpecialNull; + result->value.data.x_ptr.mut = ConstPtrMutComptimeConst; + return result; } static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, @@ -11610,6 +11631,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); } + // cast from null literal to C pointer + if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && + actual_type->id == ZigTypeIdNull) + { + return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); + } + // cast from [N]T to E![]const T if (wanted_type->id == ZigTypeIdErrorUnion && is_slice(wanted_type->data.error_union.payload_type) && @@ -12227,14 +12255,12 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * IrBinOp op_id = bin_op_instruction->op_id; bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); - if (is_equality_cmp && + if (is_equality_cmp && op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) { + return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq)); + } else if (is_equality_cmp && ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdOptional) || - (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional) || - (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull))) + (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional))) { - if (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) { - return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq)); - } IrInstruction *maybe_op; if (op1->value.type->id == ZigTypeIdNull) { maybe_op = op2; @@ -12256,6 +12282,44 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * source_node, maybe_op); is_non_null->value.type = ira->codegen->builtin_types.entry_bool; + if (op_id == IrBinOpCmpEq) { + IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, + bin_op_instruction->base.source_node, is_non_null); + result->value.type = ira->codegen->builtin_types.entry_bool; + return result; + } else { + return is_non_null; + } + } else if (is_equality_cmp && + ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && + op2->value.type->data.pointer.ptr_len == PtrLenC) || + (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && + op1->value.type->data.pointer.ptr_len == PtrLenC))) + { + IrInstruction *c_ptr_op; + if (op1->value.type->id == ZigTypeIdNull) { + c_ptr_op = op2; + } else if (op2->value.type->id == ZigTypeIdNull) { + c_ptr_op = op1; + } else { + zig_unreachable(); + } + if (instr_is_comptime(c_ptr_op)) { + ConstExprValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk); + if (!c_ptr_val) + return ira->codegen->invalid_instruction; + if (c_ptr_val->special == ConstValSpecialUndef) + return ir_const_undef(ira, &bin_op_instruction->base, ira->codegen->builtin_types.entry_bool); + bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || + (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && + c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); + bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; + return ir_const_bool(ira, &bin_op_instruction->base, bool_result); + } + IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, + source_node, c_ptr_op); + is_non_null->value.type = ira->codegen->builtin_types.entry_bool; + if (op_id == IrBinOpCmpEq) { IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, bin_op_instruction->base.source_node, is_non_null); @@ -12265,8 +12329,9 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * return is_non_null; } } else if (op1->value.type->id == ZigTypeIdNull || op2->value.type->id == ZigTypeIdNull) { - ir_add_error_node(ira, source_node, buf_sprintf("only optionals (not '%s') can compare to null", - buf_ptr(&(op1->value.type->id == ZigTypeIdNull ? op2->value.type->name : op1->value.type->name)))); + ZigType *non_null_type = (op1->value.type->id == ZigTypeIdNull) ? op2->value.type : op1->value.type; + ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", + buf_ptr(&non_null_type->name))); return ira->codegen->invalid_instruction; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 60d1a9ac89..a367532ef5 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -863,7 +863,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ _ = &x == null; \\} , - "tmp.zig:3:12: error: only optionals (not '*i32') can compare to null", + "tmp.zig:3:12: error: comparison of '*i32' with null", ); cases.add( diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig index be47718358..8b1f7d0cb8 100644 --- a/test/stage1/behavior/pointers.zig +++ b/test/stage1/behavior/pointers.zig @@ -150,3 +150,31 @@ test "allowzero pointer and slice" { expect(@typeInfo(@typeOf(ptr)).Pointer.is_allowzero); expect(@typeInfo(@typeOf(slice)).Pointer.is_allowzero); } + +test "assign null directly to C pointer and test null equality" { + var x: [*c]i32 = null; + expect(x == null); + expect(null == x); + expect(!(x != null)); + expect(!(null != x)); + + const y: [*c]i32 = null; + expect(y == null); + expect(null == y); + expect(!(y != null)); + expect(!(null != y)); + + var n: i32 = 1234; + var x1: [*c]i32 = &n; + expect(!(x1 == null)); + expect(!(null == x1)); + expect(x1 != null); + expect(null != x1); + + const nc: i32 = 1234; + const y1: [*c]const i32 = &nc; + expect(!(y1 == null)); + expect(!(null == y1)); + expect(y1 != null); + expect(null != y1); +} -- cgit v1.2.3 From 0099583bd3eccbecbb827edbde46a40cf821fecf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 8 May 2019 17:39:00 -0400 Subject: C pointers support .? operator see #1967 --- src/all_types.hpp | 7 ++++++ src/codegen.cpp | 38 +++++++++++++++++++++++++++- src/ir.cpp | 53 ++++++++++++++++++++++++++++++++++++--- src/ir_print.cpp | 9 +++++++ test/runtime_safety.zig | 20 +++++++++++++++ test/stage1/behavior/pointers.zig | 18 +++++++------ 6 files changed, 132 insertions(+), 13 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index 5a5c1cfda4..5cba3f2230 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2293,6 +2293,7 @@ enum IrInstructionId { IrInstructionIdVectorToArray, IrInstructionIdArrayToVector, IrInstructionIdAssertZero, + IrInstructionIdAssertNonNull, }; struct IrInstruction { @@ -3482,6 +3483,12 @@ struct IrInstructionAssertZero { IrInstruction *target; }; +struct IrInstructionAssertNonNull { + IrInstruction base; + + IrInstruction *target; +}; + static const size_t slice_ptr_index = 0; static const size_t slice_len_index = 1; diff --git a/src/codegen.cpp b/src/codegen.cpp index 712ee908cb..db7d96f4df 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1008,10 +1008,19 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace LLVMBuildUnreachable(g->builder); } +// TODO update most callsites to call gen_assertion instead of this static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) { gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr); } +static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) { + if (ir_want_runtime_safety(g, source_instruction)) { + gen_safety_crash(g, msg_id); + } else { + LLVMBuildUnreachable(g->builder); + } +} + static LLVMValueRef get_stacksave_fn_val(CodeGen *g) { if (g->stacksave_fn_val) return g->stacksave_fn_val; @@ -4056,8 +4065,8 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) { LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type); LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle); - LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk"); LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail"); + LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk"); LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block); LLVMPositionBuilderAtEnd(g->builder, fail_block); @@ -5487,6 +5496,31 @@ static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutable *executable, return nullptr; } +static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executable, + IrInstructionAssertNonNull *instruction) +{ + LLVMValueRef target = ir_llvm_value(g, instruction->target); + ZigType *target_type = instruction->target->value.type; + + if (target_type->id == ZigTypeIdPointer) { + assert(target_type->data.pointer.ptr_len == PtrLenC); + LLVMValueRef non_null_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target, + LLVMConstNull(get_llvm_type(g, target_type)), ""); + + LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "AssertNonNullFail"); + LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "AssertNonNullOk"); + LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block); + + LLVMPositionBuilderAtEnd(g->builder, fail_block); + gen_assertion(g, PanicMsgIdUnwrapOptionalFail, &instruction->base); + + LLVMPositionBuilderAtEnd(g->builder, ok_block); + } else { + zig_unreachable(); + } + return nullptr; +} + static void set_debug_location(CodeGen *g, IrInstruction *instruction) { AstNode *source_node = instruction->source_node; Scope *scope = instruction->scope; @@ -5741,6 +5775,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction); case IrInstructionIdAssertZero: return ir_render_assert_zero(g, executable, (IrInstructionAssertZero *)instruction); + case IrInstructionIdAssertNonNull: + return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction); case IrInstructionIdResizeSlice: return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction); } diff --git a/src/ir.cpp b/src/ir.cpp index 1b0fbd1f7f..90e8f1ed8f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1003,6 +1003,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertZero *) { return IrInstructionIdAssertZero; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) { + return IrInstructionIdAssertNonNull; +} + template static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { T *special_instruction = allocate(1); @@ -3037,6 +3041,19 @@ static IrInstruction *ir_build_assert_zero(IrAnalyze *ira, IrInstruction *source return &instruction->base; } +static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *source_instruction, + IrInstruction *target) +{ + IrInstructionAssertNonNull *instruction = ir_build_instruction(&ira->new_irb, + source_instruction->scope, source_instruction->source_node); + instruction->base.value.type = ira->codegen->builtin_types.entry_void; + instruction->target = target; + + ir_ref_instruction(target, ira->new_irb.current_basic_block); + + return &instruction->base; +} + static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { results[ReturnKindUnconditional] = 0; results[ReturnKindError] = 0; @@ -16869,6 +16886,32 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr if (type_is_invalid(type_entry)) return ira->codegen->invalid_instruction; + if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) { + if (instr_is_comptime(base_ptr)) { + ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); + if (!val) + return ira->codegen->invalid_instruction; + if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { + ConstExprValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); + if (c_ptr_val == nullptr) + return ira->codegen->invalid_instruction; + bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || + (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && + c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); + if (is_null) { + ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); + return ira->codegen->invalid_instruction; + } + return base_ptr; + } + } + if (!safety_check_on) + return base_ptr; + IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr); + ir_build_assert_non_null(ira, source_instr, c_ptr_val); + return base_ptr; + } + if (type_entry->id != ZigTypeIdOptional) { ir_add_error_node(ira, base_ptr->source_node, buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); @@ -16883,11 +16926,11 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); if (!val) return ira->codegen->invalid_instruction; - ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); - if (maybe_val == nullptr) - return ira->codegen->invalid_instruction; - if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { + ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); + if (maybe_val == nullptr) + return ira->codegen->invalid_instruction; + if (optional_value_is_null(maybe_val)) { ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); return ira->codegen->invalid_instruction; @@ -22942,6 +22985,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio case IrInstructionIdArrayToVector: case IrInstructionIdVectorToArray: case IrInstructionIdAssertZero: + case IrInstructionIdAssertNonNull: case IrInstructionIdResizeSlice: case IrInstructionIdLoadPtrGen: case IrInstructionIdBitCastGen: @@ -23346,6 +23390,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdCmpxchgGen: case IrInstructionIdCmpxchgSrc: case IrInstructionIdAssertZero: + case IrInstructionIdAssertNonNull: case IrInstructionIdResizeSlice: case IrInstructionIdGlobalAsm: return true; diff --git a/src/ir_print.cpp b/src/ir_print.cpp index dba0e4ee00..08f5cd01a4 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1003,6 +1003,12 @@ static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruct fprintf(irp->f, ")"); } +static void ir_print_assert_non_null(IrPrint *irp, IrInstructionAssertNonNull *instruction) { + fprintf(irp->f, "AssertNonNull("); + ir_print_other_instruction(irp, instruction->target); + fprintf(irp->f, ")"); +} + static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instruction) { fprintf(irp->f, "@resizeSlice("); ir_print_other_instruction(irp, instruction->operand); @@ -1880,6 +1886,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdAssertZero: ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction); break; + case IrInstructionIdAssertNonNull: + ir_print_assert_non_null(irp, (IrInstructionAssertNonNull *)instruction); + break; case IrInstructionIdResizeSlice: ir_print_resize_slice(irp, (IrInstructionResizeSlice *)instruction); break; diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig index 78b45ac05f..b10accd213 100644 --- a/test/runtime_safety.zig +++ b/test/runtime_safety.zig @@ -1,6 +1,26 @@ const tests = @import("tests.zig"); pub fn addCases(cases: *tests.CompareOutputContext) void { + cases.addRuntimeSafety(".? operator on null pointer", + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { + \\ @import("std").os.exit(126); + \\} + \\pub fn main() void { + \\ var ptr: ?*i32 = null; + \\ var b = ptr.?; + \\} + ); + + cases.addRuntimeSafety(".? operator on C pointer", + \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { + \\ @import("std").os.exit(126); + \\} + \\pub fn main() void { + \\ var ptr: [*c]i32 = null; + \\ var b = ptr.?; + \\} + ); + cases.addRuntimeSafety("@ptrToInt address zero to non-optional pointer", \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn { \\ @import("std").os.exit(126); diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig index 8b1f7d0cb8..1a7616e757 100644 --- a/test/stage1/behavior/pointers.zig +++ b/test/stage1/behavior/pointers.zig @@ -159,10 +159,10 @@ test "assign null directly to C pointer and test null equality" { expect(!(null != x)); const y: [*c]i32 = null; - expect(y == null); - expect(null == y); - expect(!(y != null)); - expect(!(null != y)); + comptime expect(y == null); + comptime expect(null == y); + comptime expect(!(y != null)); + comptime expect(!(null != y)); var n: i32 = 1234; var x1: [*c]i32 = &n; @@ -170,11 +170,13 @@ test "assign null directly to C pointer and test null equality" { expect(!(null == x1)); expect(x1 != null); expect(null != x1); + expect(x1.?.* == 1234); const nc: i32 = 1234; const y1: [*c]const i32 = &nc; - expect(!(y1 == null)); - expect(!(null == y1)); - expect(y1 != null); - expect(null != y1); + comptime expect(!(y1 == null)); + comptime expect(!(null == y1)); + comptime expect(y1 != null); + comptime expect(null != y1); + comptime expect(y1.?.* == 1234); } -- cgit v1.2.3 From 9bbd71c9ab3915b8bd8619a319a0eb6de2e2d152 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 8 May 2019 20:49:07 -0400 Subject: add --bundle-compiler-rt function to link options and use it when building libuserland.a The self-hosted part of stage1 relies on zig's compiler-rt, and so we include it in libuserland.a. This should potentially be the default, but for now it's behind a linker option. self-hosted translate-c: small progress on translating functions. --- build.zig | 1 + src-self-hosted/translate_c.zig | 38 +++- src/all_types.hpp | 1 + src/codegen.cpp | 1 + src/link.cpp | 28 +-- src/main.cpp | 5 + std/build.zig | 5 + std/special/compiler_rt.zig | 387 ++++++++++++++++++++-------------------- 8 files changed, 250 insertions(+), 216 deletions(-) (limited to 'src/codegen.cpp') diff --git a/build.zig b/build.zig index d9456e0d28..bdaf175945 100644 --- a/build.zig +++ b/build.zig @@ -389,6 +389,7 @@ fn addLibUserlandStep(b: *Builder) void { else b.addStaticLibrary("userland", "src-self-hosted/stage1.zig"); artifact.disable_gen_h = true; + artifact.bundle_compiler_rt = true; artifact.setTarget(builtin.arch, builtin.os, builtin.abi); artifact.linkSystemLibrary("c"); const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1"); diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index afe4ab0945..ddf7c6f21d 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -13,14 +13,21 @@ pub const Mode = enum { pub const ClangErrMsg = Stage2ErrorMsg; -pub const Error = error { - OutOfMemory, -}; +pub const Error = error{OutOfMemory}; const Context = struct { tree: *ast.Tree, source_buffer: *std.Buffer, err: Error, + + fn a(c: *Context) *std.mem.Allocator { + return &c.tree.arena_allocator.allocator; + } + + /// Convert a null-terminated C string to a slice allocated in the arena + fn str(c: *Context, s: [*]const u8) ![]u8 { + return std.mem.dupe(c.a(), u8, std.mem.toSliceConst(u8, s)); + } }; pub fn translate( @@ -60,12 +67,13 @@ pub fn translate( tree.* = ast.Tree{ .source = undefined, // need to use Buffer.toOwnedSlice later .root_node = root_node, - .arena_allocator = tree_arena, + .arena_allocator = undefined, .tokens = ast.Tree.TokenList.init(arena), .errors = ast.Tree.ErrorList.init(arena), }; + tree.arena_allocator = tree_arena; - var source_buffer = try std.Buffer.initSize(arena, 0); + var source_buffer = try std.Buffer.initSize(&tree.arena_allocator.allocator, 0); var context = Context{ .tree = tree, @@ -94,7 +102,7 @@ extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool { fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { switch (ZigClangDecl_getKind(decl)) { .Function => { - try appendToken(c, .LineComment, "// TODO translate function decl"); + return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl)); }, .Typedef => { try appendToken(c, .LineComment, "// TODO translate typedef"); @@ -115,11 +123,25 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void { } } -fn appendToken(c: *Context, token_id: Token.Id, src_text: []const u8) !void { +fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { + const fn_name = c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl))); + try appendToken(c, .LineComment, "// TODO translate function '{}'", fn_name); +} + +fn appendToken(c: *Context, token_id: Token.Id, comptime format: []const u8, args: ...) !void { + const S = struct { + fn callback(context: *Context, bytes: []const u8) Error!void { + return context.source_buffer.append(bytes); + } + }; const start_index = c.source_buffer.len(); - try c.source_buffer.append(src_text); + errdefer c.source_buffer.shrink(start_index); + + try std.fmt.format(c, Error, S.callback, format, args); const end_index = c.source_buffer.len(); const new_token = try c.tree.tokens.addOne(); + errdefer c.tree.tokens.shrink(c.tree.tokens.len - 1); + new_token.* = Token{ .id = token_id, .start = start_index, diff --git a/src/all_types.hpp b/src/all_types.hpp index 5cba3f2230..3cfb47db64 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1861,6 +1861,7 @@ struct CodeGen { bool each_lib_rpath; bool is_dummy_so; bool disable_gen_h; + bool bundle_compiler_rt; Buf *mmacosx_version_min; Buf *mios_version_min; diff --git a/src/codegen.cpp b/src/codegen.cpp index db7d96f4df..23d3c5dc5c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -9346,6 +9346,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { 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); diff --git a/src/link.cpp b/src/link.cpp index 385b28b71e..810f6072ad 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -772,17 +772,15 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { } } -static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) { +static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type) { // The Mach-O LLD code is not well maintained, and trips an assertion // when we link compiler_rt and builtin as libraries rather than objects. // Here we workaround this by having compiler_rt and builtin be objects. // TODO write our own linker. https://github.com/ziglang/zig/issues/1535 - OutType child_out_type = OutTypeLib; if (parent_gen->zig_target->os == OsMacOSX) { child_out_type = OutTypeObj; } - CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type, parent_gen->libc); codegen_set_out_name(child_gen, buf_create_from_str(aname)); @@ -804,14 +802,14 @@ static Buf *build_a(CodeGen *parent_gen, const char *aname) { Buf *full_path = buf_alloc(); os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); - return build_a_raw(parent_gen, aname, full_path); + return build_a_raw(parent_gen, aname, full_path, OutTypeLib); } -static Buf *build_compiler_rt(CodeGen *parent_gen) { +static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) { Buf *full_path = buf_alloc(); os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path); - return build_a_raw(parent_gen, "compiler_rt", full_path); + return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type); } static const char *get_darwin_arch_string(const ZigTarget *t) { @@ -1006,7 +1004,7 @@ static void construct_linker_job_elf(LinkJob *lj) { lj->args.append(buf_ptr(builtin_a_path)); } - Buf *compiler_rt_o_path = build_compiler_rt(g); + Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); lj->args.append(buf_ptr(compiler_rt_o_path)); } @@ -1117,7 +1115,7 @@ static void construct_linker_job_wasm(LinkJob *lj) { lj->args.append(buf_ptr(builtin_a_path)); } - Buf *compiler_rt_o_path = build_compiler_rt(g); + Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); lj->args.append(buf_ptr(compiler_rt_o_path)); } } @@ -1361,7 +1359,7 @@ static void construct_linker_job_coff(LinkJob *lj) { } // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage - Buf *compiler_rt_o_path = build_compiler_rt(g); + Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); lj->args.append(buf_ptr(compiler_rt_o_path)); } @@ -1604,7 +1602,7 @@ static void construct_linker_job_macho(LinkJob *lj) { // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce if (g->out_type == OutTypeExe || is_dyn_lib) { - Buf *compiler_rt_o_path = build_compiler_rt(g); + Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); lj->args.append(buf_ptr(compiler_rt_o_path)); } @@ -1681,14 +1679,18 @@ void codegen_link(CodeGen *g) { if (g->out_type == OutTypeLib && !g->is_dynamic) { ZigList file_names = {}; for (size_t i = 0; i < g->link_objects.length; i += 1) { - file_names.append((const char *)buf_ptr(g->link_objects.at(i))); + file_names.append(buf_ptr(g->link_objects.at(i))); + } + if (g->bundle_compiler_rt) { + Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj); + file_names.append(buf_ptr(compiler_rt_o_path)); } ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os); codegen_add_time_event(g, "LLVM Link"); if (g->verbose_link) { fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path)); - for (size_t i = 0; i < g->link_objects.length; i += 1) { - fprintf(stderr, " %s", (const char *)buf_ptr(g->link_objects.at(i))); + for (size_t i = 0; i < file_names.length; i += 1) { + fprintf(stderr, " %s", file_names.at(i)); } fprintf(stderr, "\n"); } diff --git a/src/main.cpp b/src/main.cpp index 2915fd4b9d..e9a859eb70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -86,6 +86,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --override-std-dir [arg] use an alternate Zig standard library\n" "\n" "Link Options:\n" + " --bundle-compiler-rt [path] for static libraries, include compiler-rt symbols\n" " --dynamic-linker [path] set the path to ld.so\n" " --each-lib-rpath add rpath for each used dynamic library\n" " --library [lib] link against lib\n" @@ -442,6 +443,7 @@ int main(int argc, char **argv) { TargetSubsystem subsystem = TargetSubsystemAuto; bool want_single_threaded = false; bool disable_gen_h = false; + bool bundle_compiler_rt = false; Buf *override_std_dir = nullptr; Buf *override_lib_dir = nullptr; Buf *main_pkg_path = nullptr; @@ -652,6 +654,8 @@ int main(int argc, char **argv) { want_single_threaded = true; } else if (strcmp(arg, "--disable-gen-h") == 0) { disable_gen_h = true; + } else if (strcmp(arg, "--bundle-compiler-rt") == 0) { + bundle_compiler_rt = true; } else if (strcmp(arg, "--test-cmd-bin") == 0) { test_exec_args.append(nullptr); } else if (arg[1] == 'L' && arg[2] != 0) { @@ -1070,6 +1074,7 @@ int main(int argc, char **argv) { g->verbose_cc = verbose_cc; g->output_dir = output_dir; g->disable_gen_h = disable_gen_h; + g->bundle_compiler_rt = bundle_compiler_rt; codegen_set_errmsg_color(g, color); g->system_linker_hack = system_linker_hack; diff --git a/std/build.zig b/std/build.zig index 4d6c915438..fa3bac83d0 100644 --- a/std/build.zig +++ b/std/build.zig @@ -941,6 +941,7 @@ pub const LibExeObjStep = struct { verbose_link: bool, verbose_cc: bool, disable_gen_h: bool, + bundle_compiler_rt: bool, c_std: Builder.CStd, override_std_dir: ?[]const u8, override_lib_dir: ?[]const u8, @@ -1050,6 +1051,7 @@ pub const LibExeObjStep = struct { .name_prefix = "", .filter = null, .disable_gen_h = false, + .bundle_compiler_rt = false, .output_dir = null, .need_system_paths = false, .single_threaded = false, @@ -1452,6 +1454,9 @@ pub const LibExeObjStep = struct { if (self.disable_gen_h) { try zig_args.append("--disable-gen-h"); } + if (self.bundle_compiler_rt) { + try zig_args.append("--bundle-compiler-rt"); + } switch (self.target) { Target.Native => {}, diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index 2faec8eab7..8f6f30ccc1 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -1,15 +1,13 @@ const builtin = @import("builtin"); const is_test = builtin.is_test; -const stack_probe = @import("compiler_rt/stack_probe.zig"); - comptime { const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; switch (builtin.arch) { .i386, .x86_64 => @export("__zig_probe_stack", @import("compiler_rt/stack_probe.zig").zig_probe_stack, linkage), - else => { } + else => {}, } @export("__lesf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage); @@ -499,7 +497,6 @@ nakedcc fn __aeabi_memcmp() noreturn { unreachable; } - extern fn __divmodsi4(a: i32, b: i32, rem: *i32) i32 { @setRuntimeSafety(is_test); @@ -1272,17 +1269,17 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void { test "test_divsi3" { const cases = [][3]i32{ - []i32{ 0, 1, 0}, - []i32{ 0, -1, 0}, - []i32{ 2, 1, 2}, - []i32{ 2, -1, -2}, - []i32{-2, 1, -2}, - []i32{-2, -1, 2}, - - []i32{@bitCast(i32, u32(0x80000000)), 1, @bitCast(i32, u32(0x80000000))}, - []i32{@bitCast(i32, u32(0x80000000)), -1, @bitCast(i32, u32(0x80000000))}, - []i32{@bitCast(i32, u32(0x80000000)), -2, 0x40000000}, - []i32{@bitCast(i32, u32(0x80000000)), 2, @bitCast(i32, u32(0xC0000000))}, + []i32{ 0, 1, 0 }, + []i32{ 0, -1, 0 }, + []i32{ 2, 1, 2 }, + []i32{ 2, -1, -2 }, + []i32{ -2, 1, -2 }, + []i32{ -2, -1, 2 }, + + []i32{ @bitCast(i32, u32(0x80000000)), 1, @bitCast(i32, u32(0x80000000)) }, + []i32{ @bitCast(i32, u32(0x80000000)), -1, @bitCast(i32, u32(0x80000000)) }, + []i32{ @bitCast(i32, u32(0x80000000)), -2, 0x40000000 }, + []i32{ @bitCast(i32, u32(0x80000000)), 2, @bitCast(i32, u32(0xC0000000)) }, }; for (cases) |case| { @@ -1297,19 +1294,19 @@ fn test_one_divsi3(a: i32, b: i32, expected_q: i32) void { test "test_divmodsi4" { const cases = [][4]i32{ - []i32{ 0, 1, 0, 0}, - []i32{ 0, -1, 0, 0}, - []i32{ 2, 1, 2, 0}, - []i32{ 2, -1, -2, 0}, - []i32{-2, 1, -2, 0}, - []i32{-2, -1, 2, 0}, - []i32{ 7, 5, 1, 2}, - []i32{-7, 5, -1, -2}, - []i32{19, 5, 3, 4}, - []i32{19, -5, -3, 4}, - - []i32{@bitCast(i32, u32(0x80000000)), 8, @bitCast(i32, u32(0xf0000000)), 0}, - []i32{@bitCast(i32, u32(0x80000007)), 8, @bitCast(i32, u32(0xf0000001)), -1}, + []i32{ 0, 1, 0, 0 }, + []i32{ 0, -1, 0, 0 }, + []i32{ 2, 1, 2, 0 }, + []i32{ 2, -1, -2, 0 }, + []i32{ -2, 1, -2, 0 }, + []i32{ -2, -1, 2, 0 }, + []i32{ 7, 5, 1, 2 }, + []i32{ -7, 5, -1, -2 }, + []i32{ 19, 5, 3, 4 }, + []i32{ 19, -5, -3, 4 }, + + []i32{ @bitCast(i32, u32(0x80000000)), 8, @bitCast(i32, u32(0xf0000000)), 0 }, + []i32{ @bitCast(i32, u32(0x80000007)), 8, @bitCast(i32, u32(0xf0000001)), -1 }, }; for (cases) |case| { @@ -1325,17 +1322,17 @@ fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) void { test "test_divdi3" { const cases = [][3]i64{ - []i64{ 0, 1, 0}, - []i64{ 0, -1, 0}, - []i64{ 2, 1, 2}, - []i64{ 2, -1, -2}, - []i64{-2, 1, -2}, - []i64{-2, -1, 2}, - - []i64{@bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000))}, - []i64{@bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000))}, - []i64{@bitCast(i64, u64(0x8000000000000000)), -2, 0x4000000000000000}, - []i64{@bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0xC000000000000000))}, + []i64{ 0, 1, 0 }, + []i64{ 0, -1, 0 }, + []i64{ 2, 1, 2 }, + []i64{ 2, -1, -2 }, + []i64{ -2, 1, -2 }, + []i64{ -2, -1, 2 }, + + []i64{ @bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000)) }, + []i64{ @bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000)) }, + []i64{ @bitCast(i64, u64(0x8000000000000000)), -2, 0x4000000000000000 }, + []i64{ @bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0xC000000000000000)) }, }; for (cases) |case| { @@ -1350,19 +1347,19 @@ fn test_one_divdi3(a: i64, b: i64, expected_q: i64) void { test "test_moddi3" { const cases = [][3]i64{ - []i64{0, 1, 0}, - []i64{0, -1, 0}, - []i64{5, 3, 2}, - []i64{5, -3, 2}, - []i64{-5, 3, -2}, - []i64{-5, -3, -2}, - - []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), 1, 0}, - []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), -1, 0}, - []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), 2, 0}, - []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), -2, 0}, - []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), 3, -2}, - []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), -3, -2}, + []i64{ 0, 1, 0 }, + []i64{ 0, -1, 0 }, + []i64{ 5, 3, 2 }, + []i64{ 5, -3, 2 }, + []i64{ -5, 3, -2 }, + []i64{ -5, -3, -2 }, + + []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 1, 0 }, + []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -1, 0 }, + []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 2, 0 }, + []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -2, 0 }, + []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 3, -2 }, + []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -3, -2 }, }; for (cases) |case| { @@ -1377,17 +1374,17 @@ fn test_one_moddi3(a: i64, b: i64, expected_r: i64) void { test "test_modsi3" { const cases = [][3]i32{ - []i32{0, 1, 0}, - []i32{0, -1, 0}, - []i32{5, 3, 2}, - []i32{5, -3, 2}, - []i32{-5, 3, -2}, - []i32{-5, -3, -2}, - []i32{@bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0}, - []i32{@bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0}, - []i32{@bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0}, - []i32{@bitCast(i32, @intCast(u32, 0x80000000)), 3, -2}, - []i32{@bitCast(i32, @intCast(u32, 0x80000000)), -3, -2}, + []i32{ 0, 1, 0 }, + []i32{ 0, -1, 0 }, + []i32{ 5, 3, 2 }, + []i32{ 5, -3, 2 }, + []i32{ -5, 3, -2 }, + []i32{ -5, -3, -2 }, + []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0 }, + []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0 }, + []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0 }, + []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 3, -2 }, + []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -3, -2 }, }; for (cases) |case| { @@ -1402,138 +1399,138 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) void { test "test_umodsi3" { const cases = [][3]u32{ - []u32{0x00000000, 0x00000001, 0x00000000}, - []u32{0x00000000, 0x00000002, 0x00000000}, - []u32{0x00000000, 0x00000003, 0x00000000}, - []u32{0x00000000, 0x00000010, 0x00000000}, - []u32{0x00000000, 0x078644FA, 0x00000000}, - []u32{0x00000000, 0x0747AE14, 0x00000000}, - []u32{0x00000000, 0x7FFFFFFF, 0x00000000}, - []u32{0x00000000, 0x80000000, 0x00000000}, - []u32{0x00000000, 0xFFFFFFFD, 0x00000000}, - []u32{0x00000000, 0xFFFFFFFE, 0x00000000}, - []u32{0x00000000, 0xFFFFFFFF, 0x00000000}, - []u32{0x00000001, 0x00000001, 0x00000000}, - []u32{0x00000001, 0x00000002, 0x00000001}, - []u32{0x00000001, 0x00000003, 0x00000001}, - []u32{0x00000001, 0x00000010, 0x00000001}, - []u32{0x00000001, 0x078644FA, 0x00000001}, - []u32{0x00000001, 0x0747AE14, 0x00000001}, - []u32{0x00000001, 0x7FFFFFFF, 0x00000001}, - []u32{0x00000001, 0x80000000, 0x00000001}, - []u32{0x00000001, 0xFFFFFFFD, 0x00000001}, - []u32{0x00000001, 0xFFFFFFFE, 0x00000001}, - []u32{0x00000001, 0xFFFFFFFF, 0x00000001}, - []u32{0x00000002, 0x00000001, 0x00000000}, - []u32{0x00000002, 0x00000002, 0x00000000}, - []u32{0x00000002, 0x00000003, 0x00000002}, - []u32{0x00000002, 0x00000010, 0x00000002}, - []u32{0x00000002, 0x078644FA, 0x00000002}, - []u32{0x00000002, 0x0747AE14, 0x00000002}, - []u32{0x00000002, 0x7FFFFFFF, 0x00000002}, - []u32{0x00000002, 0x80000000, 0x00000002}, - []u32{0x00000002, 0xFFFFFFFD, 0x00000002}, - []u32{0x00000002, 0xFFFFFFFE, 0x00000002}, - []u32{0x00000002, 0xFFFFFFFF, 0x00000002}, - []u32{0x00000003, 0x00000001, 0x00000000}, - []u32{0x00000003, 0x00000002, 0x00000001}, - []u32{0x00000003, 0x00000003, 0x00000000}, - []u32{0x00000003, 0x00000010, 0x00000003}, - []u32{0x00000003, 0x078644FA, 0x00000003}, - []u32{0x00000003, 0x0747AE14, 0x00000003}, - []u32{0x00000003, 0x7FFFFFFF, 0x00000003}, - []u32{0x00000003, 0x80000000, 0x00000003}, - []u32{0x00000003, 0xFFFFFFFD, 0x00000003}, - []u32{0x00000003, 0xFFFFFFFE, 0x00000003}, - []u32{0x00000003, 0xFFFFFFFF, 0x00000003}, - []u32{0x00000010, 0x00000001, 0x00000000}, - []u32{0x00000010, 0x00000002, 0x00000000}, - []u32{0x00000010, 0x00000003, 0x00000001}, - []u32{0x00000010, 0x00000010, 0x00000000}, - []u32{0x00000010, 0x078644FA, 0x00000010}, - []u32{0x00000010, 0x0747AE14, 0x00000010}, - []u32{0x00000010, 0x7FFFFFFF, 0x00000010}, - []u32{0x00000010, 0x80000000, 0x00000010}, - []u32{0x00000010, 0xFFFFFFFD, 0x00000010}, - []u32{0x00000010, 0xFFFFFFFE, 0x00000010}, - []u32{0x00000010, 0xFFFFFFFF, 0x00000010}, - []u32{0x078644FA, 0x00000001, 0x00000000}, - []u32{0x078644FA, 0x00000002, 0x00000000}, - []u32{0x078644FA, 0x00000003, 0x00000000}, - []u32{0x078644FA, 0x00000010, 0x0000000A}, - []u32{0x078644FA, 0x078644FA, 0x00000000}, - []u32{0x078644FA, 0x0747AE14, 0x003E96E6}, - []u32{0x078644FA, 0x7FFFFFFF, 0x078644FA}, - []u32{0x078644FA, 0x80000000, 0x078644FA}, - []u32{0x078644FA, 0xFFFFFFFD, 0x078644FA}, - []u32{0x078644FA, 0xFFFFFFFE, 0x078644FA}, - []u32{0x078644FA, 0xFFFFFFFF, 0x078644FA}, - []u32{0x0747AE14, 0x00000001, 0x00000000}, - []u32{0x0747AE14, 0x00000002, 0x00000000}, - []u32{0x0747AE14, 0x00000003, 0x00000002}, - []u32{0x0747AE14, 0x00000010, 0x00000004}, - []u32{0x0747AE14, 0x078644FA, 0x0747AE14}, - []u32{0x0747AE14, 0x0747AE14, 0x00000000}, - []u32{0x0747AE14, 0x7FFFFFFF, 0x0747AE14}, - []u32{0x0747AE14, 0x80000000, 0x0747AE14}, - []u32{0x0747AE14, 0xFFFFFFFD, 0x0747AE14}, - []u32{0x0747AE14, 0xFFFFFFFE, 0x0747AE14}, - []u32{0x0747AE14, 0xFFFFFFFF, 0x0747AE14}, - []u32{0x7FFFFFFF, 0x00000001, 0x00000000}, - []u32{0x7FFFFFFF, 0x00000002, 0x00000001}, - []u32{0x7FFFFFFF, 0x00000003, 0x00000001}, - []u32{0x7FFFFFFF, 0x00000010, 0x0000000F}, - []u32{0x7FFFFFFF, 0x078644FA, 0x00156B65}, - []u32{0x7FFFFFFF, 0x0747AE14, 0x043D70AB}, - []u32{0x7FFFFFFF, 0x7FFFFFFF, 0x00000000}, - []u32{0x7FFFFFFF, 0x80000000, 0x7FFFFFFF}, - []u32{0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF}, - []u32{0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF}, - []u32{0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF}, - []u32{0x80000000, 0x00000001, 0x00000000}, - []u32{0x80000000, 0x00000002, 0x00000000}, - []u32{0x80000000, 0x00000003, 0x00000002}, - []u32{0x80000000, 0x00000010, 0x00000000}, - []u32{0x80000000, 0x078644FA, 0x00156B66}, - []u32{0x80000000, 0x0747AE14, 0x043D70AC}, - []u32{0x80000000, 0x7FFFFFFF, 0x00000001}, - []u32{0x80000000, 0x80000000, 0x00000000}, - []u32{0x80000000, 0xFFFFFFFD, 0x80000000}, - []u32{0x80000000, 0xFFFFFFFE, 0x80000000}, - []u32{0x80000000, 0xFFFFFFFF, 0x80000000}, - []u32{0xFFFFFFFD, 0x00000001, 0x00000000}, - []u32{0xFFFFFFFD, 0x00000002, 0x00000001}, - []u32{0xFFFFFFFD, 0x00000003, 0x00000001}, - []u32{0xFFFFFFFD, 0x00000010, 0x0000000D}, - []u32{0xFFFFFFFD, 0x078644FA, 0x002AD6C9}, - []u32{0xFFFFFFFD, 0x0747AE14, 0x01333341}, - []u32{0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE}, - []u32{0xFFFFFFFD, 0x80000000, 0x7FFFFFFD}, - []u32{0xFFFFFFFD, 0xFFFFFFFD, 0x00000000}, - []u32{0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD}, - []u32{0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD}, - []u32{0xFFFFFFFE, 0x00000001, 0x00000000}, - []u32{0xFFFFFFFE, 0x00000002, 0x00000000}, - []u32{0xFFFFFFFE, 0x00000003, 0x00000002}, - []u32{0xFFFFFFFE, 0x00000010, 0x0000000E}, - []u32{0xFFFFFFFE, 0x078644FA, 0x002AD6CA}, - []u32{0xFFFFFFFE, 0x0747AE14, 0x01333342}, - []u32{0xFFFFFFFE, 0x7FFFFFFF, 0x00000000}, - []u32{0xFFFFFFFE, 0x80000000, 0x7FFFFFFE}, - []u32{0xFFFFFFFE, 0xFFFFFFFD, 0x00000001}, - []u32{0xFFFFFFFE, 0xFFFFFFFE, 0x00000000}, - []u32{0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE}, - []u32{0xFFFFFFFF, 0x00000001, 0x00000000}, - []u32{0xFFFFFFFF, 0x00000002, 0x00000001}, - []u32{0xFFFFFFFF, 0x00000003, 0x00000000}, - []u32{0xFFFFFFFF, 0x00000010, 0x0000000F}, - []u32{0xFFFFFFFF, 0x078644FA, 0x002AD6CB}, - []u32{0xFFFFFFFF, 0x0747AE14, 0x01333343}, - []u32{0xFFFFFFFF, 0x7FFFFFFF, 0x00000001}, - []u32{0xFFFFFFFF, 0x80000000, 0x7FFFFFFF}, - []u32{0xFFFFFFFF, 0xFFFFFFFD, 0x00000002}, - []u32{0xFFFFFFFF, 0xFFFFFFFE, 0x00000001}, - []u32{0xFFFFFFFF, 0xFFFFFFFF, 0x00000000} + []u32{ 0x00000000, 0x00000001, 0x00000000 }, + []u32{ 0x00000000, 0x00000002, 0x00000000 }, + []u32{ 0x00000000, 0x00000003, 0x00000000 }, + []u32{ 0x00000000, 0x00000010, 0x00000000 }, + []u32{ 0x00000000, 0x078644FA, 0x00000000 }, + []u32{ 0x00000000, 0x0747AE14, 0x00000000 }, + []u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 }, + []u32{ 0x00000000, 0x80000000, 0x00000000 }, + []u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 }, + []u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 }, + []u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 }, + []u32{ 0x00000001, 0x00000001, 0x00000000 }, + []u32{ 0x00000001, 0x00000002, 0x00000001 }, + []u32{ 0x00000001, 0x00000003, 0x00000001 }, + []u32{ 0x00000001, 0x00000010, 0x00000001 }, + []u32{ 0x00000001, 0x078644FA, 0x00000001 }, + []u32{ 0x00000001, 0x0747AE14, 0x00000001 }, + []u32{ 0x00000001, 0x7FFFFFFF, 0x00000001 }, + []u32{ 0x00000001, 0x80000000, 0x00000001 }, + []u32{ 0x00000001, 0xFFFFFFFD, 0x00000001 }, + []u32{ 0x00000001, 0xFFFFFFFE, 0x00000001 }, + []u32{ 0x00000001, 0xFFFFFFFF, 0x00000001 }, + []u32{ 0x00000002, 0x00000001, 0x00000000 }, + []u32{ 0x00000002, 0x00000002, 0x00000000 }, + []u32{ 0x00000002, 0x00000003, 0x00000002 }, + []u32{ 0x00000002, 0x00000010, 0x00000002 }, + []u32{ 0x00000002, 0x078644FA, 0x00000002 }, + []u32{ 0x00000002, 0x0747AE14, 0x00000002 }, + []u32{ 0x00000002, 0x7FFFFFFF, 0x00000002 }, + []u32{ 0x00000002, 0x80000000, 0x00000002 }, + []u32{ 0x00000002, 0xFFFFFFFD, 0x00000002 }, + []u32{ 0x00000002, 0xFFFFFFFE, 0x00000002 }, + []u32{ 0x00000002, 0xFFFFFFFF, 0x00000002 }, + []u32{ 0x00000003, 0x00000001, 0x00000000 }, + []u32{ 0x00000003, 0x00000002, 0x00000001 }, + []u32{ 0x00000003, 0x00000003, 0x00000000 }, + []u32{ 0x00000003, 0x00000010, 0x00000003 }, + []u32{ 0x00000003, 0x078644FA, 0x00000003 }, + []u32{ 0x00000003, 0x0747AE14, 0x00000003 }, + []u32{ 0x00000003, 0x7FFFFFFF, 0x00000003 }, + []u32{ 0x00000003, 0x80000000, 0x00000003 }, + []u32{ 0x00000003, 0xFFFFFFFD, 0x00000003 }, + []u32{ 0x00000003, 0xFFFFFFFE, 0x00000003 }, + []u32{ 0x00000003, 0xFFFFFFFF, 0x00000003 }, + []u32{ 0x00000010, 0x00000001, 0x00000000 }, + []u32{ 0x00000010, 0x00000002, 0x00000000 }, + []u32{ 0x00000010, 0x00000003, 0x00000001 }, + []u32{ 0x00000010, 0x00000010, 0x00000000 }, + []u32{ 0x00000010, 0x078644FA, 0x00000010 }, + []u32{ 0x00000010, 0x0747AE14, 0x00000010 }, + []u32{ 0x00000010, 0x7FFFFFFF, 0x00000010 }, + []u32{ 0x00000010, 0x80000000, 0x00000010 }, + []u32{ 0x00000010, 0xFFFFFFFD, 0x00000010 }, + []u32{ 0x00000010, 0xFFFFFFFE, 0x00000010 }, + []u32{ 0x00000010, 0xFFFFFFFF, 0x00000010 }, + []u32{ 0x078644FA, 0x00000001, 0x00000000 }, + []u32{ 0x078644FA, 0x00000002, 0x00000000 }, + []u32{ 0x078644FA, 0x00000003, 0x00000000 }, + []u32{ 0x078644FA, 0x00000010, 0x0000000A }, + []u32{ 0x078644FA, 0x078644FA, 0x00000000 }, + []u32{ 0x078644FA, 0x0747AE14, 0x003E96E6 }, + []u32{ 0x078644FA, 0x7FFFFFFF, 0x078644FA }, + []u32{ 0x078644FA, 0x80000000, 0x078644FA }, + []u32{ 0x078644FA, 0xFFFFFFFD, 0x078644FA }, + []u32{ 0x078644FA, 0xFFFFFFFE, 0x078644FA }, + []u32{ 0x078644FA, 0xFFFFFFFF, 0x078644FA }, + []u32{ 0x0747AE14, 0x00000001, 0x00000000 }, + []u32{ 0x0747AE14, 0x00000002, 0x00000000 }, + []u32{ 0x0747AE14, 0x00000003, 0x00000002 }, + []u32{ 0x0747AE14, 0x00000010, 0x00000004 }, + []u32{ 0x0747AE14, 0x078644FA, 0x0747AE14 }, + []u32{ 0x0747AE14, 0x0747AE14, 0x00000000 }, + []u32{ 0x0747AE14, 0x7FFFFFFF, 0x0747AE14 }, + []u32{ 0x0747AE14, 0x80000000, 0x0747AE14 }, + []u32{ 0x0747AE14, 0xFFFFFFFD, 0x0747AE14 }, + []u32{ 0x0747AE14, 0xFFFFFFFE, 0x0747AE14 }, + []u32{ 0x0747AE14, 0xFFFFFFFF, 0x0747AE14 }, + []u32{ 0x7FFFFFFF, 0x00000001, 0x00000000 }, + []u32{ 0x7FFFFFFF, 0x00000002, 0x00000001 }, + []u32{ 0x7FFFFFFF, 0x00000003, 0x00000001 }, + []u32{ 0x7FFFFFFF, 0x00000010, 0x0000000F }, + []u32{ 0x7FFFFFFF, 0x078644FA, 0x00156B65 }, + []u32{ 0x7FFFFFFF, 0x0747AE14, 0x043D70AB }, + []u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000 }, + []u32{ 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF }, + []u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF }, + []u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF }, + []u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF }, + []u32{ 0x80000000, 0x00000001, 0x00000000 }, + []u32{ 0x80000000, 0x00000002, 0x00000000 }, + []u32{ 0x80000000, 0x00000003, 0x00000002 }, + []u32{ 0x80000000, 0x00000010, 0x00000000 }, + []u32{ 0x80000000, 0x078644FA, 0x00156B66 }, + []u32{ 0x80000000, 0x0747AE14, 0x043D70AC }, + []u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 }, + []u32{ 0x80000000, 0x80000000, 0x00000000 }, + []u32{ 0x80000000, 0xFFFFFFFD, 0x80000000 }, + []u32{ 0x80000000, 0xFFFFFFFE, 0x80000000 }, + []u32{ 0x80000000, 0xFFFFFFFF, 0x80000000 }, + []u32{ 0xFFFFFFFD, 0x00000001, 0x00000000 }, + []u32{ 0xFFFFFFFD, 0x00000002, 0x00000001 }, + []u32{ 0xFFFFFFFD, 0x00000003, 0x00000001 }, + []u32{ 0xFFFFFFFD, 0x00000010, 0x0000000D }, + []u32{ 0xFFFFFFFD, 0x078644FA, 0x002AD6C9 }, + []u32{ 0xFFFFFFFD, 0x0747AE14, 0x01333341 }, + []u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE }, + []u32{ 0xFFFFFFFD, 0x80000000, 0x7FFFFFFD }, + []u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000000 }, + []u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD }, + []u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD }, + []u32{ 0xFFFFFFFE, 0x00000001, 0x00000000 }, + []u32{ 0xFFFFFFFE, 0x00000002, 0x00000000 }, + []u32{ 0xFFFFFFFE, 0x00000003, 0x00000002 }, + []u32{ 0xFFFFFFFE, 0x00000010, 0x0000000E }, + []u32{ 0xFFFFFFFE, 0x078644FA, 0x002AD6CA }, + []u32{ 0xFFFFFFFE, 0x0747AE14, 0x01333342 }, + []u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000000 }, + []u32{ 0xFFFFFFFE, 0x80000000, 0x7FFFFFFE }, + []u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 }, + []u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000000 }, + []u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE }, + []u32{ 0xFFFFFFFF, 0x00000001, 0x00000000 }, + []u32{ 0xFFFFFFFF, 0x00000002, 0x00000001 }, + []u32{ 0xFFFFFFFF, 0x00000003, 0x00000000 }, + []u32{ 0xFFFFFFFF, 0x00000010, 0x0000000F }, + []u32{ 0xFFFFFFFF, 0x078644FA, 0x002AD6CB }, + []u32{ 0xFFFFFFFF, 0x0747AE14, 0x01333343 }, + []u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000001 }, + []u32{ 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF }, + []u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000002 }, + []u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 }, + []u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 }, }; for (cases) |case| { -- cgit v1.2.3 From a7346ea49f4d9b1af2d0babf67354b234a87fe42 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 8 May 2019 22:43:11 -0400 Subject: fix build on macOS Sadly due to a workaround for LLD linker limitations on macOS we cannot put libuserland into an .a file; instead we have to use object files. Again due to linker limitations, bundling compiler_rt.o into another relocatable object also doesn't work. So we're left with disabling stack probing on macOS for the stage1 self-hosted code. These workarounds could all be removed if the macos support in the LLD linker improved, or if Zig project had its own linker that did not have these issues. --- build.zig | 7 ++++++- src/all_types.hpp | 1 + src/codegen.cpp | 8 +++++++- src/codegen.hpp | 1 + src/link.cpp | 10 ++++++---- src/main.cpp | 5 +++++ std/build.zig | 5 +++++ 7 files changed, 31 insertions(+), 6 deletions(-) (limited to 'src/codegen.cpp') diff --git a/build.zig b/build.zig index bdaf175945..274ea51436 100644 --- a/build.zig +++ b/build.zig @@ -384,12 +384,17 @@ const Context = struct { }; fn addLibUserlandStep(b: *Builder) void { + // Sadly macOS requires hacks to work around the buggy MACH-O linker code. const artifact = if (builtin.os == .macosx) b.addObject("userland", "src-self-hosted/stage1.zig") else b.addStaticLibrary("userland", "src-self-hosted/stage1.zig"); artifact.disable_gen_h = true; - artifact.bundle_compiler_rt = true; + if (builtin.os == .macosx) { + artifact.disable_stack_probing = true; + } else { + artifact.bundle_compiler_rt = true; + } artifact.setTarget(builtin.arch, builtin.os, builtin.abi); artifact.linkSystemLibrary("c"); const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1"); diff --git a/src/all_types.hpp b/src/all_types.hpp index 3cfb47db64..ecc0d1a9bb 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1862,6 +1862,7 @@ struct CodeGen { bool is_dummy_so; bool disable_gen_h; bool bundle_compiler_rt; + bool disable_stack_probing; Buf *mmacosx_version_min; Buf *mios_version_min; diff --git a/src/codegen.cpp b/src/codegen.cpp index 23d3c5dc5c..d21ada1b23 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -401,7 +401,7 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { static void add_probe_stack_attr(CodeGen *g, LLVMValueRef fn_val) { // Windows already emits its own stack probes - if (g->zig_target->os != OsWindows && + if (!g->disable_stack_probing && g->zig_target->os != OsWindows && (g->zig_target->arch == ZigLLVM_x86 || g->zig_target->arch == ZigLLVM_x86_64)) { addLLVMFnAttrStr(fn_val, "probe-stack", "__zig_probe_stack"); @@ -7043,6 +7043,11 @@ static void zig_llvm_emit_output(CodeGen *g) { } validate_inline_fns(g); g->link_objects.append(output_path); + if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || + (g->out_type == OutTypeLib && !g->is_dynamic))) + { + zig_link_add_compiler_rt(g); + } break; case EmitFileTypeAssembly: @@ -9347,6 +9352,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->each_lib_rpath); cache_bool(ch, g->disable_gen_h); cache_bool(ch, g->bundle_compiler_rt); + cache_bool(ch, g->disable_stack_probing); cache_bool(ch, want_valgrind_support(g)); cache_bool(ch, g->have_pic); cache_bool(ch, g->have_dynamic_link); diff --git a/src/codegen.hpp b/src/codegen.hpp index 88c7353cad..47c0097e4b 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -44,6 +44,7 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc void codegen_add_time_event(CodeGen *g, const char *name); void codegen_print_timing_report(CodeGen *g, FILE *f); void codegen_link(CodeGen *g); +void zig_link_add_compiler_rt(CodeGen *g); void codegen_build_and_link(CodeGen *g); ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path, diff --git a/src/link.cpp b/src/link.cpp index 810f6072ad..8900d0351b 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -25,6 +25,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type, parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path()); child_gen->disable_gen_h = true; + child_gen->disable_stack_probing = true; child_gen->verbose_tokenize = parent_gen->verbose_tokenize; child_gen->verbose_ast = parent_gen->verbose_ast; child_gen->verbose_link = parent_gen->verbose_link; @@ -1653,6 +1654,11 @@ static void construct_linker_job(LinkJob *lj) { } } +void zig_link_add_compiler_rt(CodeGen *g) { + Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj); + g->link_objects.append(compiler_rt_o_path); +} + void codegen_link(CodeGen *g) { codegen_add_time_event(g, "Build Dependencies"); @@ -1681,10 +1687,6 @@ void codegen_link(CodeGen *g) { for (size_t i = 0; i < g->link_objects.length; i += 1) { file_names.append(buf_ptr(g->link_objects.at(i))); } - if (g->bundle_compiler_rt) { - Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj); - file_names.append(buf_ptr(compiler_rt_o_path)); - } ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os); codegen_add_time_event(g, "LLVM Link"); if (g->verbose_link) { diff --git a/src/main.cpp b/src/main.cpp index e9a859eb70..5659624cb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,6 +56,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --disable-gen-h do not generate a C header file (.h)\n" " --disable-valgrind omit valgrind client requests in debug builds\n" " --enable-valgrind include valgrind client requests release builds\n" + " --disable-stack-probing workaround for macosx\n" " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" " -fPIC enable Position Independent Code\n" " -fno-PIC disable Position Independent Code\n" @@ -444,6 +445,7 @@ int main(int argc, char **argv) { bool want_single_threaded = false; bool disable_gen_h = false; bool bundle_compiler_rt = false; + bool disable_stack_probing = false; Buf *override_std_dir = nullptr; Buf *override_lib_dir = nullptr; Buf *main_pkg_path = nullptr; @@ -656,6 +658,8 @@ int main(int argc, char **argv) { disable_gen_h = true; } else if (strcmp(arg, "--bundle-compiler-rt") == 0) { bundle_compiler_rt = true; + } else if (strcmp(arg, "--disable-stack-probing") == 0) { + disable_stack_probing = true; } else if (strcmp(arg, "--test-cmd-bin") == 0) { test_exec_args.append(nullptr); } else if (arg[1] == 'L' && arg[2] != 0) { @@ -1075,6 +1079,7 @@ int main(int argc, char **argv) { g->output_dir = output_dir; g->disable_gen_h = disable_gen_h; g->bundle_compiler_rt = bundle_compiler_rt; + g->disable_stack_probing = disable_stack_probing; codegen_set_errmsg_color(g, color); g->system_linker_hack = system_linker_hack; diff --git a/std/build.zig b/std/build.zig index fa3bac83d0..b5ec97ab5f 100644 --- a/std/build.zig +++ b/std/build.zig @@ -942,6 +942,7 @@ pub const LibExeObjStep = struct { verbose_cc: bool, disable_gen_h: bool, bundle_compiler_rt: bool, + disable_stack_probing: bool, c_std: Builder.CStd, override_std_dir: ?[]const u8, override_lib_dir: ?[]const u8, @@ -1052,6 +1053,7 @@ pub const LibExeObjStep = struct { .filter = null, .disable_gen_h = false, .bundle_compiler_rt = false, + .disable_stack_probing = false, .output_dir = null, .need_system_paths = false, .single_threaded = false, @@ -1457,6 +1459,9 @@ pub const LibExeObjStep = struct { if (self.bundle_compiler_rt) { try zig_args.append("--bundle-compiler-rt"); } + if (self.disable_stack_probing) { + try zig_args.append("--disable-stack-probing"); + } switch (self.target) { Target.Native => {}, -- cgit v1.2.3