From ecd2332bb5c74739ade40f1b9eaf412b4642a36f Mon Sep 17 00:00:00 2001 From: emekoi Date: Fri, 29 Mar 2019 19:25:47 -0500 Subject: [PATCH 001/285] made lld flags on windows consistent --- src/link.cpp | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/link.cpp b/src/link.cpp index c2d46f0ac6..65f4060105 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1122,14 +1122,14 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si } static void add_uefi_link_args(LinkJob *lj) { - lj->args.append("/BASE:0"); - lj->args.append("/ENTRY:EfiMain"); - lj->args.append("/OPT:REF"); - lj->args.append("/SAFESEH:NO"); - lj->args.append("/MERGE:.rdata=.data"); - lj->args.append("/ALIGN:32"); - lj->args.append("/NODEFAULTLIB"); - lj->args.append("/SECTION:.xdata,D"); + lj->args.append("-BASE:0"); + lj->args.append("-ENTRY:EfiMain"); + lj->args.append("-OPT:REF"); + lj->args.append("-SAFESEH:NO"); + lj->args.append("-MERGE:.rdata=.data"); + lj->args.append("-ALIGN:32"); + lj->args.append("-NODEFAULTLIB"); + lj->args.append("-SECTION:.xdata,D"); } static void add_nt_link_args(LinkJob *lj, bool is_library) { @@ -1163,12 +1163,12 @@ static void add_nt_link_args(LinkJob *lj, bool is_library) { lj->args.append("kernel32.lib"); lj->args.append("ntdll.lib"); } else { - lj->args.append("/NODEFAULTLIB"); + lj->args.append("-NODEFAULTLIB"); if (!is_library) { if (g->have_winmain) { - lj->args.append("/ENTRY:WinMain"); + lj->args.append("-ENTRY:WinMain"); } else { - lj->args.append("/ENTRY:WinMainCRTStartup"); + lj->args.append("-ENTRY:WinMainCRTStartup"); } } } @@ -1178,17 +1178,17 @@ static void construct_linker_job_coff(LinkJob *lj) { Error err; CodeGen *g = lj->codegen; - lj->args.append("/ERRORLIMIT:0"); + lj->args.append("-ERRORLIMIT:0"); - lj->args.append("/NOLOGO"); + lj->args.append("-NOLOGO"); if (!g->strip_debug_symbols) { - lj->args.append("/DEBUG"); + lj->args.append("-DEBUG"); } if (g->out_type == OutTypeExe) { // TODO compile time stack upper bound detection - lj->args.append("/STACK:16777216"); + lj->args.append("-STACK:16777216"); } coff_append_machine_arg(g, &lj->args); @@ -1203,35 +1203,35 @@ static void construct_linker_job_coff(LinkJob *lj) { } break; case TargetSubsystemConsole: - lj->args.append("/SUBSYSTEM:console"); + lj->args.append("-SUBSYSTEM:console"); add_nt_link_args(lj, is_library); break; case TargetSubsystemEfiApplication: - lj->args.append("/SUBSYSTEM:efi_application"); + lj->args.append("-SUBSYSTEM:efi_application"); add_uefi_link_args(lj); break; case TargetSubsystemEfiBootServiceDriver: - lj->args.append("/SUBSYSTEM:efi_boot_service_driver"); + lj->args.append("-SUBSYSTEM:efi_boot_service_driver"); add_uefi_link_args(lj); break; case TargetSubsystemEfiRom: - lj->args.append("/SUBSYSTEM:efi_rom"); + lj->args.append("-SUBSYSTEM:efi_rom"); add_uefi_link_args(lj); break; case TargetSubsystemEfiRuntimeDriver: - lj->args.append("/SUBSYSTEM:efi_runtime_driver"); + lj->args.append("-SUBSYSTEM:efi_runtime_driver"); add_uefi_link_args(lj); break; case TargetSubsystemNative: - lj->args.append("/SUBSYSTEM:native"); + lj->args.append("-SUBSYSTEM:native"); add_nt_link_args(lj, is_library); break; case TargetSubsystemPosix: - lj->args.append("/SUBSYSTEM:posix"); + lj->args.append("-SUBSYSTEM:posix"); add_nt_link_args(lj, is_library); break; case TargetSubsystemWindows: - lj->args.append("/SUBSYSTEM:windows"); + lj->args.append("-SUBSYSTEM:windows"); add_nt_link_args(lj, is_library); break; } From 6cc443ee457d06ea23713bb78ab832d886029d57 Mon Sep 17 00:00:00 2001 From: emekoi Date: Fri, 29 Mar 2019 20:37:15 -0500 Subject: [PATCH 002/285] added code for linking libc on mingw --- src/link.cpp | 198 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 143 insertions(+), 55 deletions(-) diff --git a/src/link.cpp b/src/link.cpp index 65f4060105..d7532d96e3 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1132,40 +1132,114 @@ static void add_uefi_link_args(LinkJob *lj) { lj->args.append("-SECTION:.xdata,D"); } -static void add_nt_link_args(LinkJob *lj, bool is_library) { +static void add_msvc_link_args(LinkJob *lj, bool is_library) { CodeGen *g = lj->codegen; - if (lj->link_in_crt) { - // TODO: https://github.com/ziglang/zig/issues/2064 - bool is_dynamic = true; // g->is_dynamic; - const char *lib_str = is_dynamic ? "" : "lib"; - const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; + // TODO: https://github.com/ziglang/zig/issues/2064 + bool is_dynamic = true; // g->is_dynamic; + const char *lib_str = is_dynamic ? "" : "lib"; + const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : ""; - if (!is_dynamic) { - Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str); - lj->args.append(buf_ptr(cmt_lib_name)); + if (!is_dynamic) { + Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str); + lj->args.append(buf_ptr(cmt_lib_name)); + } else { + Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str); + lj->args.append(buf_ptr(msvcrt_lib_name)); + } + + Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str); + lj->args.append(buf_ptr(vcruntime_lib_name)); + + Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str); + lj->args.append(buf_ptr(crt_lib_name)); + + //Visual C++ 2015 Conformance Changes + //https://msdn.microsoft.com/en-us/library/bb531344.aspx + lj->args.append("legacy_stdio_definitions.lib"); + + // msvcrt depends on kernel32 and ntdll + lj->args.append("kernel32.lib"); + lj->args.append("ntdll.lib"); +} + +static const char *get_libc_file(ZigLibCInstallation *lib, const char *file) { + Buf *out_buf = buf_alloc(); + os_path_join(&lib->crt_dir, buf_create_from_str(file), out_buf); + return buf_ptr(out_buf); +} + +static const char *get_libc_static_file(ZigLibCInstallation *lib, const char *file) { + Buf *static_crt_dir = buf_alloc(); + Buf *out_buf = buf_alloc(); + if (zig_libc_cc_print_file_name(file, static_crt_dir, true, true) != ErrorNone) { + abort(); + } + os_path_join(static_crt_dir, buf_create_from_str(file), out_buf); + return buf_ptr(out_buf); +} + +static void add_gnu_link_args(LinkJob *lj, bool is_library) { + CodeGen *g = lj->codegen; + + bool is_dll = g->out_type == OutTypeLib && g->is_dynamic; + + if (g->zig_target->arch == ZigLLVM_x86) { + lj->args.append("-ALTERNATENAME:__image_base__=___ImageBase"); + } else { + lj->args.append("-ALTERNATENAME:__image_base__=__ImageBase"); + } + + if (is_dll) { + lj->args.append(get_libc_file(g->libc, "dllcrt2.o")); + } else { + lj->args.append(get_libc_file(g->libc, "crt2.o")); + } + + lj->args.append(get_libc_static_file(g->libc, "crtbegin.o")); + + if (g->libc_link_lib != nullptr) { + lj->args.append("libmingw32.a"); + + if (is_dll) { + lj->args.append(get_libc_static_file(g->libc, "libgcc_s.a")); + lj->args.append(get_libc_static_file(g->libc, "libgcc.a")); } else { - Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str); - lj->args.append(buf_ptr(msvcrt_lib_name)); + lj->args.append(get_libc_static_file(g->libc, "libgcc.a")); + lj->args.append(get_libc_static_file(g->libc, "libgcc_eh.a")); } - Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str); - lj->args.append(buf_ptr(vcruntime_lib_name)); + lj->args.append(get_libc_static_file(g->libc, "libssp.a")); + lj->args.append("libmoldname.a"); + lj->args.append("libmingwex.a"); + lj->args.append("libmsvcrt.a"); - Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str); - lj->args.append(buf_ptr(crt_lib_name)); + if (g->subsystem == TargetSubsystemWindows) { + lj->args.append("libgdi32.a"); + lj->args.append("libcomdlg32.a"); + } - //Visual C++ 2015 Conformance Changes - //https://msdn.microsoft.com/en-us/library/bb531344.aspx - lj->args.append("legacy_stdio_definitions.lib"); + lj->args.append("libadvapi32.a"); + lj->args.append("libadvapi32.a"); + lj->args.append("libshell32.a"); + lj->args.append("libuser32.a"); + lj->args.append("libkernel32.a"); - // msvcrt depends on kernel32 and ntdll - lj->args.append("kernel32.lib"); - lj->args.append("ntdll.lib"); + lj->args.append(get_libc_static_file(g->libc, "crtend.o")); + } +} + +static void add_win_link_args(LinkJob *lj, bool is_library) { + if (lj->link_in_crt) { + if (target_abi_is_gnu(lj->codegen->zig_target->abi)) { + add_gnu_link_args(lj, is_library); + } else { + add_msvc_link_args(lj, is_library); + } } else { lj->args.append("-NODEFAULTLIB"); if (!is_library) { - if (g->have_winmain) { + if (lj->codegen->have_winmain) { lj->args.append("-ENTRY:WinMain"); } else { lj->args.append("-ENTRY:WinMainCRTStartup"); @@ -1194,17 +1268,46 @@ static void construct_linker_job_coff(LinkJob *lj) { coff_append_machine_arg(g, &lj->args); bool is_library = g->out_type == OutTypeLib; + if (is_library && g->is_dynamic) { + lj->args.append("-DLL"); + } + + lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); + + if (g->libc_link_lib != nullptr) { + assert(g->libc != nullptr); + + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir)))); + + if (target_abi_is_gnu(g->zig_target->abi)) { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->sys_include_dir)))); + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->include_dir)))); + } else { + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir)))); + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir)))); + } + } + + for (size_t i = 0; i < g->lib_dirs.length; i += 1) { + const char *lib_dir = g->lib_dirs.at(i); + lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir))); + } + + for (size_t i = 0; i < g->link_objects.length; i += 1) { + lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); + } + switch (g->subsystem) { case TargetSubsystemAuto: if (g->zig_target->os == OsUefi) { add_uefi_link_args(lj); } else { - add_nt_link_args(lj, is_library); + add_win_link_args(lj, is_library); } break; case TargetSubsystemConsole: lj->args.append("-SUBSYSTEM:console"); - add_nt_link_args(lj, is_library); + add_win_link_args(lj, is_library); break; case TargetSubsystemEfiApplication: lj->args.append("-SUBSYSTEM:efi_application"); @@ -1224,41 +1327,18 @@ static void construct_linker_job_coff(LinkJob *lj) { break; case TargetSubsystemNative: lj->args.append("-SUBSYSTEM:native"); - add_nt_link_args(lj, is_library); + add_win_link_args(lj, is_library); break; case TargetSubsystemPosix: lj->args.append("-SUBSYSTEM:posix"); - add_nt_link_args(lj, is_library); + add_win_link_args(lj, is_library); break; case TargetSubsystemWindows: lj->args.append("-SUBSYSTEM:windows"); - add_nt_link_args(lj, is_library); + add_win_link_args(lj, is_library); break; } - lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); - - if (g->libc_link_lib != nullptr) { - assert(g->libc != nullptr); - - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir)))); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir)))); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir)))); - } - - if (is_library && g->is_dynamic) { - lj->args.append("-DLL"); - } - - for (size_t i = 0; i < g->lib_dirs.length; i += 1) { - const char *lib_dir = g->lib_dirs.at(i); - lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir))); - } - - for (size_t i = 0; i < g->link_objects.length; i += 1) { - lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); - } - if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) { if (g->libc_link_lib == nullptr && !g->is_dummy_so) { Buf *builtin_a_path = build_a(g, "builtin"); @@ -1278,11 +1358,19 @@ static void construct_linker_job_coff(LinkJob *lj) { continue; } if (link_lib->provided_explicitly) { - if (lj->codegen->zig_target->abi == ZigLLVM_GNU) { - Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name)); - lj->args.append(buf_ptr(arg)); - } - else { + if (target_abi_is_gnu(lj->codegen->zig_target->abi)) { + static const char *test_names[3] = { "lib%s.dll.a", "lib%s.a", nullptr }; + + for (size_t i = 0; test_names[i] != nullptr; i++) { + Buf *test_path = buf_sprintf(test_names[i], buf_ptr(link_lib->name)); + bool exists = false; + if (os_file_exists(test_path, &exists) != ErrorNone) { + zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path)); + } else if (exists) { + lj->args.append(buf_ptr(test_path)); + } + } + } else { lj->args.append(buf_ptr(link_lib->name)); } } else { From 0bd4901a174786a61fadf484f3b8932169533cd4 Mon Sep 17 00:00:00 2001 From: emekoi Date: Sat, 30 Mar 2019 00:06:04 -0500 Subject: [PATCH 003/285] fixed linking of system libraries on mingw --- src/libc_installation.hpp | 2 -- src/link.cpp | 24 ++++++++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/libc_installation.hpp b/src/libc_installation.hpp index 765ae4ec56..171cc963bf 100644 --- a/src/libc_installation.hpp +++ b/src/libc_installation.hpp @@ -29,8 +29,6 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file); Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose); -#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_WINDOWS) Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose); -#endif #endif diff --git a/src/link.cpp b/src/link.cpp index d7532d96e3..00d70d5e63 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1359,17 +1359,25 @@ static void construct_linker_job_coff(LinkJob *lj) { } if (link_lib->provided_explicitly) { if (target_abi_is_gnu(lj->codegen->zig_target->abi)) { - static const char *test_names[3] = { "lib%s.dll.a", "lib%s.a", nullptr }; + static const char *test_names[3] = { "%s\\lib%s.dll.a", "%s\\lib%s.a", nullptr }; + bool exists = false; - for (size_t i = 0; test_names[i] != nullptr; i++) { - Buf *test_path = buf_sprintf(test_names[i], buf_ptr(link_lib->name)); - bool exists = false; - if (os_file_exists(test_path, &exists) != ErrorNone) { - zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path)); - } else if (exists) { - lj->args.append(buf_ptr(test_path)); + for (size_t i = 0; test_names[i] != nullptr && !exists; i++) { + for (size_t j = 0; j < g->lib_dirs.length; j += 1) { + const char *lib_dir = g->lib_dirs.at(j); + Buf *test_path = buf_sprintf(test_names[i], lib_dir, buf_ptr(link_lib->name)); + if (os_file_exists(test_path, &exists) != ErrorNone) { + zig_panic("link: unable to check if file exists: %s", buf_ptr(test_path)); + } else if (exists) { + lj->args.append(buf_ptr(test_path)); + break; + } } } + + if (!exists) { + zig_panic("link: unable to find library: %s", buf_ptr(link_lib->name)); + } } else { lj->args.append(buf_ptr(link_lib->name)); } From 6960cd156addc23492ddbb3c1b7627a63d2ba46a Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Sun, 7 Apr 2019 03:18:51 +0200 Subject: [PATCH 004/285] Added regression test for #1607. fixes #1607 --- test/stage1/behavior/bugs/1607.zig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 test/stage1/behavior/bugs/1607.zig diff --git a/test/stage1/behavior/bugs/1607.zig b/test/stage1/behavior/bugs/1607.zig new file mode 100644 index 0000000000..04c894a35e --- /dev/null +++ b/test/stage1/behavior/bugs/1607.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const testing = std.testing; + +const a = []u8{1,2,3}; + +fn checkAddress(s: []const u8) void { + for (s) |*i, j| { + testing.expect(i == &a[j]); + } +} + +test "slices pointing at the same address as global array." { + checkAddress(a); + comptime checkAddress(a); +} \ No newline at end of file From 627b52fe654a7506861d3cbefb705803bd0c5102 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Sat, 6 Apr 2019 16:31:28 +0900 Subject: [PATCH 005/285] src/ir.cpp: don't call-out to analyze_type_expr; replaces `analyze_type_expr` with `ir_analyze_type_expr` --- src/ir.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index c572e3c885..de4543df4e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -356,6 +356,28 @@ static void ir_ref_var(ZigVar *var) { var->ref_count += 1; } +ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { + ConstExprValue *result = ir_eval_const_value( ira->codegen + , scope + , node + , ira->codegen->builtin_types.entry_type + , ira->new_irb.exec->backward_branch_count + , ira->new_irb.exec->backward_branch_quota + , nullptr + , nullptr + , node + , nullptr + , ira->new_irb.exec + , nullptr + ); + + if (type_is_invalid(result->type)) + return ira->codegen->builtin_types.entry_invalid; + + assert(result->special != ConstValSpecialRuntime); + return result->data.x_type; +} + static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) { IrBasicBlock *result = allocate(1); result->scope = scope; @@ -13875,7 +13897,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node IrInstruction *casted_arg; if (param_decl_node->data.param_decl.var_token == nullptr) { AstNode *param_type_node = param_decl_node->data.param_decl.type; - ZigType *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node); + ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); if (type_is_invalid(param_type)) return false; @@ -13915,7 +13937,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod } else { if (param_decl_node->data.param_decl.var_token == nullptr) { AstNode *param_type_node = param_decl_node->data.param_decl.type; - ZigType *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node); + ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); if (type_is_invalid(param_type)) return false; @@ -14296,7 +14318,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call } AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; - ZigType *specified_return_type = analyze_type_expr(ira->codegen, exec_scope, return_type_node); + ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node); if (type_is_invalid(specified_return_type)) return ira->codegen->invalid_instruction; ZigType *return_type; @@ -14532,7 +14554,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call if (fn_proto_node->data.fn_proto.return_var_token == nullptr) { AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; - ZigType *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node); + ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); if (type_is_invalid(specified_return_type)) return ira->codegen->invalid_instruction; if (fn_proto_node->data.fn_proto.auto_err_set) { @@ -14559,7 +14581,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call if (call_instruction->is_async) { AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type; if (async_allocator_type_node != nullptr) { - ZigType *async_allocator_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, async_allocator_type_node); + ZigType *async_allocator_type = ir_analyze_type_expr(ira, impl_fn->child_scope, async_allocator_type_node); if (type_is_invalid(async_allocator_type)) return ira->codegen->invalid_instruction; inst_fn_type_id.async_allocator_type = async_allocator_type; From fae0c35195076c8bce9da3528ce8d1959902ca06 Mon Sep 17 00:00:00 2001 From: kristopher tate Date: Sun, 7 Apr 2019 10:36:10 +0900 Subject: [PATCH 006/285] test/compile_errors.zig: add regression test for ziglang/zig#532 ; --- test/compile_errors.zig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/compile_errors.zig b/test/compile_errors.zig index a31605b02a..0d30bd7175 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,21 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "Generic function where return type is self-referenced", + \\fn Foo(comptime T: type) Foo(T) { + \\ return struct{ x: T }; + \\} + \\export fn entry() void { + \\ const t = Foo(u32) { + \\ .x = 1 + \\ }; + \\} + , + "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches", + "tmp.zig:1:29: note: called from here", + ); + cases.add( "@ptrToInt 0 to non optional pointer", \\export fn entry() void { From 6a78b315b2112e372b48ba7399ea9cddadbe65b6 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Sat, 6 Apr 2019 14:15:12 -0700 Subject: [PATCH 007/285] Fix std.HashMap.remove returning incorrect KV Now returns a copy of the removed kv instead of a pointer to the removed kv. The removed kv gets overwritten when shifting the hash map after the removal, so returning a pointer to it will have another kv's values in it after the return. This bug had some nasty downstream effects in things like BufSet and BufMap where delete would free a still in-use KV and leave the actually removed KV un-free'd. --- std/hash_map.zig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/std/hash_map.zig b/std/hash_map.zig index f4c0b87167..6ea128c9ad 100644 --- a/std/hash_map.zig +++ b/std/hash_map.zig @@ -175,7 +175,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 return hm.get(key) != null; } - pub fn remove(hm: *Self, key: K) ?*KV { + pub fn remove(hm: *Self, key: K) ?KV { if (hm.entries.len == 0) return null; hm.incrementModificationCount(); const start_index = hm.keyToIndex(key); @@ -189,13 +189,14 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 if (!eql(entry.kv.key, key)) continue; + const removed_kv = entry.kv; while (roll_over < hm.entries.len) : (roll_over += 1) { const next_index = (start_index + roll_over + 1) % hm.entries.len; const next_entry = &hm.entries[next_index]; if (!next_entry.used or next_entry.distance_from_start_index == 0) { entry.used = false; hm.size -= 1; - return &entry.kv; + return removed_kv; } entry.* = next_entry.*; entry.distance_from_start_index -= 1; @@ -371,7 +372,10 @@ test "basic hash map usage" { testing.expect(map.contains(2)); testing.expect(map.get(2).?.value == 22); - _ = map.remove(2); + + const rmv1 = map.remove(2); + testing.expect(rmv1.?.key == 2); + testing.expect(rmv1.?.value == 22); testing.expect(map.remove(2) == null); testing.expect(map.get(2) == null); } From f86ea797ba1387c0cf06987f42a82b0afdff20b4 Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Mon, 8 Apr 2019 05:30:27 +0200 Subject: [PATCH 008/285] Import 1607.zig to behavior.zig --- test/stage1/behavior.zig | 1 + test/stage1/behavior/bugs/1607.zig | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index da90660bf1..bdd2273c34 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -20,6 +20,7 @@ comptime { _ = @import("behavior/bugs/1442.zig"); _ = @import("behavior/bugs/1486.zig"); _ = @import("behavior/bugs/1500.zig"); + _ = @import("behavior/bugs/1607.zig"); _ = @import("behavior/bugs/1851.zig"); _ = @import("behavior/bugs/1914.zig"); _ = @import("behavior/bugs/2006.zig"); diff --git a/test/stage1/behavior/bugs/1607.zig b/test/stage1/behavior/bugs/1607.zig index 04c894a35e..f32eeb03d6 100644 --- a/test/stage1/behavior/bugs/1607.zig +++ b/test/stage1/behavior/bugs/1607.zig @@ -1,7 +1,7 @@ const std = @import("std"); const testing = std.testing; -const a = []u8{1,2,3}; +const a = []u8{ 1, 2, 3 }; fn checkAddress(s: []const u8) void { for (s) |*i, j| { @@ -12,4 +12,4 @@ fn checkAddress(s: []const u8) void { test "slices pointing at the same address as global array." { checkAddress(a); comptime checkAddress(a); -} \ No newline at end of file +} From bddbbef32b4a42237ca84352a26a93bf250da918 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Apr 2019 15:41:41 -0400 Subject: [PATCH 009/285] Release 0.4.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 69a087f980..8588c3ae9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) set(ZIG_VERSION_MAJOR 0) -set(ZIG_VERSION_MINOR 3) +set(ZIG_VERSION_MINOR 4) set(ZIG_VERSION_PATCH 0) set(ZIG_VERSION "${ZIG_VERSION_MAJOR}.${ZIG_VERSION_MINOR}.${ZIG_VERSION_PATCH}") From 98fa065de722bb7981949117a66643ed9eac8c52 Mon Sep 17 00:00:00 2001 From: Jay Weisskopf Date: Mon, 8 Apr 2019 23:54:36 -0400 Subject: [PATCH 010/285] docs: Underline link when hovering over it In addition to the pointer, this gives some visual feedback to the user that the element is interactive. This is a very common style pattern across the web. --- doc/langref.html.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index bb2a67c562..1d80c73a3e 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -8,7 +8,7 @@ body{ font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif; } - a { + a:not(:hover) { text-decoration: none; } table, th, td { From cca02a4cf8fc59a221abd41d26bb2f1e03a869ee Mon Sep 17 00:00:00 2001 From: Jay Weisskopf Date: Mon, 8 Apr 2019 20:21:18 -0400 Subject: [PATCH 011/285] Update README headline to match website --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 77ed6d22c6..0a860e4e5d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![ZIG](https://ziglang.org/zig-logo.svg) -A programming language designed for robustness, optimality, and -clarity. +Zig is an open-source programming language designed for **robustness**, +**optimality**, and **maintainability**. [Download & Documentation](https://ziglang.org/download/) From dea1027f9799e6ce0f7f2594c6b555d9675c281a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 9 Apr 2019 17:37:35 -0400 Subject: [PATCH 012/285] doc comments for parameters in std.mem.Allocator --- std/mem.zig | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/std/mem.zig b/std/mem.zig index 9bf68698c9..46cfda2d94 100644 --- a/std/mem.zig +++ b/std/mem.zig @@ -34,39 +34,39 @@ pub const Allocator = struct { /// The returned slice must have its pointer aligned at least to `new_alignment` bytes. reallocFn: fn ( self: *Allocator, - // Guaranteed to be the same as what was returned from most recent call to - // `reallocFn` or `shrinkFn`. - // If `old_mem.len == 0` then this is a new allocation and `new_byte_count` - // is guaranteed to be >= 1. + /// Guaranteed to be the same as what was returned from most recent call to + /// `reallocFn` or `shrinkFn`. + /// If `old_mem.len == 0` then this is a new allocation and `new_byte_count` + /// is guaranteed to be >= 1. old_mem: []u8, - // If `old_mem.len == 0` then this is `undefined`, otherwise: - // Guaranteed to be the same as what was returned from most recent call to - // `reallocFn` or `shrinkFn`. - // Guaranteed to be >= 1. - // Guaranteed to be a power of 2. + /// If `old_mem.len == 0` then this is `undefined`, otherwise: + /// Guaranteed to be the same as what was returned from most recent call to + /// `reallocFn` or `shrinkFn`. + /// Guaranteed to be >= 1. + /// Guaranteed to be a power of 2. old_alignment: u29, - // If `new_byte_count` is 0 then this is a free and it is guaranteed that - // `old_mem.len != 0`. + /// If `new_byte_count` is 0 then this is a free and it is guaranteed that + /// `old_mem.len != 0`. new_byte_count: usize, - // Guaranteed to be >= 1. - // Guaranteed to be a power of 2. - // Returned slice's pointer must have this alignment. + /// Guaranteed to be >= 1. + /// Guaranteed to be a power of 2. + /// Returned slice's pointer must have this alignment. new_alignment: u29, ) Error![]u8, /// This function deallocates memory. It must succeed. shrinkFn: fn ( self: *Allocator, - // Guaranteed to be the same as what was returned from most recent call to - // `reallocFn` or `shrinkFn`. + /// Guaranteed to be the same as what was returned from most recent call to + /// `reallocFn` or `shrinkFn`. old_mem: []u8, - // Guaranteed to be the same as what was returned from most recent call to - // `reallocFn` or `shrinkFn`. + /// Guaranteed to be the same as what was returned from most recent call to + /// `reallocFn` or `shrinkFn`. old_alignment: u29, - // Guaranteed to be less than or equal to `old_mem.len`. + /// Guaranteed to be less than or equal to `old_mem.len`. new_byte_count: usize, - // If `new_byte_count == 0` then this is `undefined`, otherwise: - // Guaranteed to be less than or equal to `old_alignment`. + /// If `new_byte_count == 0` then this is `undefined`, otherwise: + /// Guaranteed to be less than or equal to `old_alignment`. new_alignment: u29, ) []u8, From aff2e47821aaad5cac74ed8a3cac2e72283b594b Mon Sep 17 00:00:00 2001 From: vegecode Date: Sun, 7 Apr 2019 22:17:21 -0500 Subject: [PATCH 013/285] compiler-rt: correct use_thumb_1 flag The flag is for generating correct arm-thumb interwork veneers in the assembly code __aeabi_{memcpy,memset,etc} functions. Armv6m only does thumb code generation regardless of whether arm or thumb is selected and armv6t2 uses the newer thumb 2 set. All other versions that zig supports pre-armv7 need the veneers and hence the flag. Armv5 is actually armv5t. Relevant code from clang/lib/Basic/Targets/Arm.cpp ```c bool ARMTargetInfo::isThumb() const { return ArchISA == llvm::ARM::ISAKind::THUMB; } bool ARMTargetInfo::supportsThumb() const { return CPUAttr.count('T') || ArchVersion >= 6; } bool ARMTargetInfo::supportsThumb2() const { return CPUAttr.equals("6T2") || (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE")); } ``` Also see http://www.llvm.org/svn/llvm-project/llvm/trunk/lib/Target/ARM/ARM.td --- std/special/compiler_rt.zig | 77 +++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index e8d522eea1..f15cf42be2 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -253,14 +253,75 @@ const is_arm_arch = switch (builtin.arch) { const is_arm_32 = is_arm_arch and !is_arm_64; -const use_thumb_1 = is_arm_32 and switch (builtin.arch.arm) { - builtin.Arch.Arm32.v6, - builtin.Arch.Arm32.v6m, - builtin.Arch.Arm32.v6k, - builtin.Arch.Arm32.v6t2, - => true, - else => false, -}; +const use_thumb_1 = usesThumb1(builtin.arch); + +fn usesThumb1(arch: builtin.Arch) bool { + return switch (arch) { + .arm => switch (arch.arm) { + .v6m => true, + else => false, + }, + .armeb => switch (arch.armeb) { + .v6m => true, + else => false, + }, + .thumb => switch (arch.thumb) { + .v5, + .v5te, + .v4t, + .v6, + .v6m, + .v6k, + => true, + else => false, + }, + .thumbeb => switch (arch.thumbeb) { + .v5, + .v5te, + .v4t, + .v6, + .v6m, + .v6k, + => true, + else => false, + }, + else => false, + }; +} + +test "usesThumb1" { + testing.expect(usesThumb1(builtin.Arch{ .arm = .v6m })); + testing.expect(!usesThumb1(builtin.Arch{ .arm = .v5 })); + //etc. + + testing.expect(usesThumb1(builtin.Arch{ .armeb = .v6m })); + testing.expect(!usesThumb1(builtin.Arch{ .armeb = .v5 })); + //etc. + + testing.expect(usesThumb1(builtin.Arch{ .thumb = .v5 })); + testing.expect(usesThumb1(builtin.Arch{ .thumb = .v5te })); + testing.expect(usesThumb1(builtin.Arch{ .thumb = .v4t })); + testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6 })); + testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6k })); + testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6m })); + testing.expect(!usesThumb1(builtin.Arch{ .thumb = .v6t2 })); + //etc. + + testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v5 })); + testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v5te })); + testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v4t })); + testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6 })); + testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6k })); + testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6m })); + testing.expect(!usesThumb1(builtin.Arch{ .thumbeb = .v6t2 })); + //etc. + + testing.expect(!usesThumb1(builtin.Arch{ .aarch64 = .v8 })); + testing.expect(!usesThumb1(builtin.Arch{ .aarch64_be = .v8 })); + testing.expect(!usesThumb1(builtin.Arch.x86_64)); + testing.expect(!usesThumb1(builtin.Arch.riscv32)); + //etc. +} nakedcc fn __aeabi_uidivmod() void { @setRuntimeSafety(false); From 52934851f2b7a5cb28a08beafa1ec1aa24a3a4cb Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 10 Apr 2019 16:29:10 -0400 Subject: [PATCH 014/285] compiler_rt: `@divTrunc` rather than `@divFloor` in muloti4 --- std/special/compiler_rt/muloti4.zig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/std/special/compiler_rt/muloti4.zig b/std/special/compiler_rt/muloti4.zig index fd6855072b..f5820fa37d 100644 --- a/std/special/compiler_rt/muloti4.zig +++ b/std/special/compiler_rt/muloti4.zig @@ -1,4 +1,3 @@ -const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); @@ -33,11 +32,11 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 { } if (sa == sb) { - if (abs_a > @divFloor(max, abs_b)) { + if (abs_a > @divTrunc(max, abs_b)) { overflow.* = 1; } } else { - if (abs_a > @divFloor(min, -abs_b)) { + if (abs_a > @divTrunc(min, -abs_b)) { overflow.* = 1; } } From 60e2a04322cb3cb49fdc2c1b28060bc261754302 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 10 Apr 2019 23:30:41 +0200 Subject: [PATCH 015/285] Correct parsing of DWARF line_info section --- std/debug.zig | 304 ++++++++++++++++++++++++-------------------------- 1 file changed, 146 insertions(+), 158 deletions(-) diff --git a/std/debug.zig b/std/debug.zig index c85a982059..2bef2e69cc 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -1213,7 +1213,6 @@ const CompileUnit = struct { version: u16, is_64: bool, die: *Die, - index: usize, pc_range: ?PcRange, }; @@ -1787,173 +1786,165 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !LineInfo { const compile_unit_cwd = try compile_unit.die.getAttrString(di, DW.AT_comp_dir); + const line_info_offset = try compile_unit.die.getAttrSecOffset(DW.AT_stmt_list); - const debug_line_end = di.debug_line.offset + di.debug_line.size; - var this_offset = di.debug_line.offset; - var this_index: usize = 0; + assert(line_info_offset < di.debug_line.size); - while (this_offset < debug_line_end) : (this_index += 1) { - try di.dwarf_seekable_stream.seekTo(this_offset); + try di.dwarf_seekable_stream.seekTo(di.debug_line.offset + line_info_offset); - var is_64: bool = undefined; - const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64); - if (unit_length == 0) return error.MissingDebugInfo; - const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); + var is_64: bool = undefined; + const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64); + if (unit_length == 0) { + return error.MissingDebugInfo; + } + const next_offset = unit_length + (if (is_64) usize(12) else usize(4)); - if (compile_unit.index != this_index) { - this_offset += next_offset; - continue; + const version = try di.dwarf_in_stream.readInt(u16, di.endian); + // TODO support 3 and 5 + if (version != 2 and version != 4) return error.InvalidDebugInfo; + + const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian); + const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length; + + const minimum_instruction_length = try di.dwarf_in_stream.readByte(); + if (minimum_instruction_length == 0) return error.InvalidDebugInfo; + + if (version >= 4) { + // maximum_operations_per_instruction + _ = try di.dwarf_in_stream.readByte(); + } + + const default_is_stmt = (try di.dwarf_in_stream.readByte()) != 0; + const line_base = try di.dwarf_in_stream.readByteSigned(); + + const line_range = try di.dwarf_in_stream.readByte(); + if (line_range == 0) return error.InvalidDebugInfo; + + const opcode_base = try di.dwarf_in_stream.readByte(); + + const standard_opcode_lengths = try di.allocator().alloc(u8, opcode_base - 1); + + { + var i: usize = 0; + while (i < opcode_base - 1) : (i += 1) { + standard_opcode_lengths[i] = try di.dwarf_in_stream.readByte(); } + } - const version = try di.dwarf_in_stream.readInt(u16, di.endian); - // TODO support 3 and 5 - if (version != 2 and version != 4) return error.InvalidDebugInfo; + var include_directories = ArrayList([]u8).init(di.allocator()); + try include_directories.append(compile_unit_cwd); + while (true) { + const dir = try di.readString(); + if (dir.len == 0) break; + try include_directories.append(dir); + } - const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian); - const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length; + var file_entries = ArrayList(FileEntry).init(di.allocator()); + var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address); - const minimum_instruction_length = try di.dwarf_in_stream.readByte(); - if (minimum_instruction_length == 0) return error.InvalidDebugInfo; + while (true) { + const file_name = try di.readString(); + if (file_name.len == 0) break; + const dir_index = try readULeb128(di.dwarf_in_stream); + const mtime = try readULeb128(di.dwarf_in_stream); + const len_bytes = try readULeb128(di.dwarf_in_stream); + try file_entries.append(FileEntry{ + .file_name = file_name, + .dir_index = dir_index, + .mtime = mtime, + .len_bytes = len_bytes, + }); + } - if (version >= 4) { - // maximum_operations_per_instruction - _ = try di.dwarf_in_stream.readByte(); - } + try di.dwarf_seekable_stream.seekTo(prog_start_offset); - const default_is_stmt = (try di.dwarf_in_stream.readByte()) != 0; - const line_base = try di.dwarf_in_stream.readByteSigned(); + while (true) { + const opcode = try di.dwarf_in_stream.readByte(); - const line_range = try di.dwarf_in_stream.readByte(); - if (line_range == 0) return error.InvalidDebugInfo; - - const opcode_base = try di.dwarf_in_stream.readByte(); - - const standard_opcode_lengths = try di.allocator().alloc(u8, opcode_base - 1); - - { - var i: usize = 0; - while (i < opcode_base - 1) : (i += 1) { - standard_opcode_lengths[i] = try di.dwarf_in_stream.readByte(); + if (opcode == DW.LNS_extended_op) { + const op_size = try readULeb128(di.dwarf_in_stream); + if (op_size < 1) return error.InvalidDebugInfo; + var sub_op = try di.dwarf_in_stream.readByte(); + switch (sub_op) { + DW.LNE_end_sequence => { + prog.end_sequence = true; + if (try prog.checkLineMatch()) |info| return info; + return error.MissingDebugInfo; + }, + DW.LNE_set_address => { + const addr = try di.dwarf_in_stream.readInt(usize, di.endian); + prog.address = addr; + }, + DW.LNE_define_file => { + const file_name = try di.readString(); + const dir_index = try readULeb128(di.dwarf_in_stream); + const mtime = try readULeb128(di.dwarf_in_stream); + const len_bytes = try readULeb128(di.dwarf_in_stream); + try file_entries.append(FileEntry{ + .file_name = file_name, + .dir_index = dir_index, + .mtime = mtime, + .len_bytes = len_bytes, + }); + }, + else => { + const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo; + try di.dwarf_seekable_stream.seekForward(fwd_amt); + }, + } + } else if (opcode >= opcode_base) { + // special opcodes + const adjusted_opcode = opcode - opcode_base; + const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range); + const inc_line = i32(line_base) + i32(adjusted_opcode % line_range); + prog.line += inc_line; + prog.address += inc_addr; + if (try prog.checkLineMatch()) |info| return info; + prog.basic_block = false; + } else { + switch (opcode) { + DW.LNS_copy => { + if (try prog.checkLineMatch()) |info| return info; + prog.basic_block = false; + }, + DW.LNS_advance_pc => { + const arg = try readULeb128(di.dwarf_in_stream); + prog.address += arg * minimum_instruction_length; + }, + DW.LNS_advance_line => { + const arg = try readILeb128(di.dwarf_in_stream); + prog.line += arg; + }, + DW.LNS_set_file => { + const arg = try readULeb128(di.dwarf_in_stream); + prog.file = arg; + }, + DW.LNS_set_column => { + const arg = try readULeb128(di.dwarf_in_stream); + prog.column = arg; + }, + DW.LNS_negate_stmt => { + prog.is_stmt = !prog.is_stmt; + }, + DW.LNS_set_basic_block => { + prog.basic_block = true; + }, + DW.LNS_const_add_pc => { + const inc_addr = minimum_instruction_length * ((255 - opcode_base) / line_range); + prog.address += inc_addr; + }, + DW.LNS_fixed_advance_pc => { + const arg = try di.dwarf_in_stream.readInt(u16, di.endian); + prog.address += arg; + }, + DW.LNS_set_prologue_end => {}, + else => { + if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo; + const len_bytes = standard_opcode_lengths[opcode - 1]; + try di.dwarf_seekable_stream.seekForward(len_bytes); + }, } } - - var include_directories = ArrayList([]u8).init(di.allocator()); - try include_directories.append(compile_unit_cwd); - while (true) { - const dir = try di.readString(); - if (dir.len == 0) break; - try include_directories.append(dir); - } - - var file_entries = ArrayList(FileEntry).init(di.allocator()); - var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address); - - while (true) { - const file_name = try di.readString(); - if (file_name.len == 0) break; - const dir_index = try readULeb128(di.dwarf_in_stream); - const mtime = try readULeb128(di.dwarf_in_stream); - const len_bytes = try readULeb128(di.dwarf_in_stream); - try file_entries.append(FileEntry{ - .file_name = file_name, - .dir_index = dir_index, - .mtime = mtime, - .len_bytes = len_bytes, - }); - } - - try di.dwarf_seekable_stream.seekTo(prog_start_offset); - - while (true) { - const opcode = try di.dwarf_in_stream.readByte(); - - if (opcode == DW.LNS_extended_op) { - const op_size = try readULeb128(di.dwarf_in_stream); - if (op_size < 1) return error.InvalidDebugInfo; - var sub_op = try di.dwarf_in_stream.readByte(); - switch (sub_op) { - DW.LNE_end_sequence => { - prog.end_sequence = true; - if (try prog.checkLineMatch()) |info| return info; - return error.MissingDebugInfo; - }, - DW.LNE_set_address => { - const addr = try di.dwarf_in_stream.readInt(usize, di.endian); - prog.address = addr; - }, - DW.LNE_define_file => { - const file_name = try di.readString(); - const dir_index = try readULeb128(di.dwarf_in_stream); - const mtime = try readULeb128(di.dwarf_in_stream); - const len_bytes = try readULeb128(di.dwarf_in_stream); - try file_entries.append(FileEntry{ - .file_name = file_name, - .dir_index = dir_index, - .mtime = mtime, - .len_bytes = len_bytes, - }); - }, - else => { - const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo; - try di.dwarf_seekable_stream.seekForward(fwd_amt); - }, - } - } else if (opcode >= opcode_base) { - // special opcodes - const adjusted_opcode = opcode - opcode_base; - const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range); - const inc_line = i32(line_base) + i32(adjusted_opcode % line_range); - prog.line += inc_line; - prog.address += inc_addr; - if (try prog.checkLineMatch()) |info| return info; - prog.basic_block = false; - } else { - switch (opcode) { - DW.LNS_copy => { - if (try prog.checkLineMatch()) |info| return info; - prog.basic_block = false; - }, - DW.LNS_advance_pc => { - const arg = try readULeb128(di.dwarf_in_stream); - prog.address += arg * minimum_instruction_length; - }, - DW.LNS_advance_line => { - const arg = try readILeb128(di.dwarf_in_stream); - prog.line += arg; - }, - DW.LNS_set_file => { - const arg = try readULeb128(di.dwarf_in_stream); - prog.file = arg; - }, - DW.LNS_set_column => { - const arg = try readULeb128(di.dwarf_in_stream); - prog.column = arg; - }, - DW.LNS_negate_stmt => { - prog.is_stmt = !prog.is_stmt; - }, - DW.LNS_set_basic_block => { - prog.basic_block = true; - }, - DW.LNS_const_add_pc => { - const inc_addr = minimum_instruction_length * ((255 - opcode_base) / line_range); - prog.address += inc_addr; - }, - DW.LNS_fixed_advance_pc => { - const arg = try di.dwarf_in_stream.readInt(u16, di.endian); - prog.address += arg; - }, - DW.LNS_set_prologue_end => {}, - else => { - if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo; - const len_bytes = standard_opcode_lengths[opcode - 1]; - try di.dwarf_seekable_stream.seekForward(len_bytes); - }, - } - } - } - - this_offset += next_offset; } return error.MissingDebugInfo; @@ -1962,7 +1953,6 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr fn scanAllCompileUnits(di: *DwarfInfo) !void { const debug_info_end = di.debug_info.offset + di.debug_info.size; var this_unit_offset = di.debug_info.offset; - var cu_index: usize = 0; while (this_unit_offset < debug_info_end) { try di.dwarf_seekable_stream.seekTo(this_unit_offset); @@ -2019,11 +2009,9 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void { .is_64 = is_64, .pc_range = pc_range, .die = compile_unit_die, - .index = cu_index, }); this_unit_offset += next_offset; - cu_index += 1; } } From a71bfc249d3f814d7d659fe5cf4cb582483e8938 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 10 Apr 2019 18:47:14 -0400 Subject: [PATCH 016/285] 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 +- std/special/compiler_rt.zig | 13 ++----------- std/special/compiler_rt/divti3.zig | 6 +++--- std/special/compiler_rt/modti3.zig | 6 +++--- std/special/compiler_rt/muloti4.zig | 6 +++--- std/special/compiler_rt/multi3.zig | 6 +++--- std/special/compiler_rt/udivmodti4.zig | 5 +++-- std/special/compiler_rt/udivti3.zig | 5 +++-- std/special/compiler_rt/umodti3.zig | 6 +++--- 9 files changed, 24 insertions(+), 31 deletions(-) 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); } } diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index f15cf42be2..6eb87cbd93 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -160,6 +160,8 @@ comptime { @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); @export("__modti3", @import("compiler_rt/modti3.zig").__modti3_windows_x86_64, linkage); @export("__multi3", @import("compiler_rt/multi3.zig").__multi3_windows_x86_64, linkage); @@ -198,17 +200,6 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn } } -pub fn setXmm0(comptime T: type, value: T) void { - comptime assert(builtin.arch == builtin.Arch.x86_64); - const aligned_value: T align(16) = value; - asm volatile ( - \\movaps (%[ptr]), %%xmm0 - : - : [ptr] "r" (&aligned_value) - : "xmm0" - ); -} - extern fn __udivdi3(a: u64, b: u64) u64 { @setRuntimeSafety(is_test); return __udivmoddi4(a, b, null); diff --git a/std/special/compiler_rt/divti3.zig b/std/special/compiler_rt/divti3.zig index e89a1ada5c..d5b2778a34 100644 --- a/std/special/compiler_rt/divti3.zig +++ b/std/special/compiler_rt/divti3.zig @@ -16,9 +16,9 @@ pub extern fn __divti3(a: i128, b: i128) i128 { return (@bitCast(i128, r) ^ s) -% s; } -pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void { - @setRuntimeSafety(builtin.is_test); - compiler_rt.setXmm0(i128, __divti3(a.*, b.*)); +const v128 = @Vector(2, u64); +pub extern fn __divti3_windows_x86_64(a: v128, b: v128) v128 { + return @bitCast(v128, @inlineCall(__divti3, @bitCast(i128, a), @bitCast(i128, b))); } test "import divti3" { diff --git a/std/special/compiler_rt/modti3.zig b/std/special/compiler_rt/modti3.zig index 03222cadf5..16f2f38ba3 100644 --- a/std/special/compiler_rt/modti3.zig +++ b/std/special/compiler_rt/modti3.zig @@ -20,9 +20,9 @@ pub extern fn __modti3(a: i128, b: i128) i128 { return (@bitCast(i128, r) ^ s_a) -% s_a; // negate if s == -1 } -pub extern fn __modti3_windows_x86_64(a: *const i128, b: *const i128) void { - @setRuntimeSafety(builtin.is_test); - compiler_rt.setXmm0(i128, __modti3(a.*, b.*)); +const v128 = @Vector(2, u64); +pub extern fn __modti3_windows_x86_64(a: v128, b: v128) v128 { + return @bitCast(v128, @inlineCall(__modti3, @bitCast(i128, a), @bitCast(i128, b))); } test "import modti3" { diff --git a/std/special/compiler_rt/muloti4.zig b/std/special/compiler_rt/muloti4.zig index f5820fa37d..65953f3e1d 100644 --- a/std/special/compiler_rt/muloti4.zig +++ b/std/special/compiler_rt/muloti4.zig @@ -44,9 +44,9 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 { return r; } -pub extern fn __muloti4_windows_x86_64(a: *const i128, b: *const i128, overflow: *c_int) void { - @setRuntimeSafety(builtin.is_test); - compiler_rt.setXmm0(i128, __muloti4(a.*, b.*, overflow)); +const v128 = @Vector(2, u64); +pub extern fn __muloti4_windows_x86_64(a: v128, b: v128, overflow: *c_int) v128 { + return @bitCast(v128, @inlineCall(__muloti4, @bitCast(i128, a), @bitCast(i128, b), overflow)); } test "import muloti4" { diff --git a/std/special/compiler_rt/multi3.zig b/std/special/compiler_rt/multi3.zig index a0c84adaf4..799b1f575d 100644 --- a/std/special/compiler_rt/multi3.zig +++ b/std/special/compiler_rt/multi3.zig @@ -14,9 +14,9 @@ pub extern fn __multi3(a: i128, b: i128) i128 { return r.all; } -pub extern fn __multi3_windows_x86_64(a: *const i128, b: *const i128) void { - @setRuntimeSafety(builtin.is_test); - compiler_rt.setXmm0(i128, __multi3(a.*, b.*)); +const v128 = @Vector(2, u64); +pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 { + return @bitCast(v128, @inlineCall(__multi3, @bitCast(i128, a), @bitCast(i128, b))); } fn __mulddi3(a: u64, b: u64) i128 { diff --git a/std/special/compiler_rt/udivmodti4.zig b/std/special/compiler_rt/udivmodti4.zig index 6a037d3bae..c74dff512d 100644 --- a/std/special/compiler_rt/udivmodti4.zig +++ b/std/special/compiler_rt/udivmodti4.zig @@ -7,9 +7,10 @@ pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) u128 { return udivmod(u128, a, b, maybe_rem); } -pub extern fn __udivmodti4_windows_x86_64(a: *const u128, b: *const u128, maybe_rem: ?*u128) void { +const v128 = @Vector(2, u64); +pub extern fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) v128 { @setRuntimeSafety(builtin.is_test); - compiler_rt.setXmm0(u128, udivmod(u128, a.*, b.*, maybe_rem)); + return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem)); } test "import udivmodti4" { diff --git a/std/special/compiler_rt/udivti3.zig b/std/special/compiler_rt/udivti3.zig index 510e21ac1d..ab451859bf 100644 --- a/std/special/compiler_rt/udivti3.zig +++ b/std/special/compiler_rt/udivti3.zig @@ -6,7 +6,8 @@ pub extern fn __udivti3(a: u128, b: u128) u128 { return udivmodti4.__udivmodti4(a, b, null); } -pub extern fn __udivti3_windows_x86_64(a: *const u128, b: *const u128) void { +const v128 = @Vector(2, u64); +pub extern fn __udivti3_windows_x86_64(a: v128, b: v128) v128 { @setRuntimeSafety(builtin.is_test); - udivmodti4.__udivmodti4_windows_x86_64(a, b, null); + return udivmodti4.__udivmodti4_windows_x86_64(a, b, null); } diff --git a/std/special/compiler_rt/umodti3.zig b/std/special/compiler_rt/umodti3.zig index 12aca8b036..7add0b2ffe 100644 --- a/std/special/compiler_rt/umodti3.zig +++ b/std/special/compiler_rt/umodti3.zig @@ -9,7 +9,7 @@ pub extern fn __umodti3(a: u128, b: u128) u128 { return r; } -pub extern fn __umodti3_windows_x86_64(a: *const u128, b: *const u128) void { - @setRuntimeSafety(builtin.is_test); - compiler_rt.setXmm0(u128, __umodti3(a.*, b.*)); +const v128 = @Vector(2, u64); +pub extern fn __umodti3_windows_x86_64(a: v128, b: v128) v128 { + return @bitCast(v128, @inlineCall(__umodti3, @bitCast(u128, a), @bitCast(u128, b))); } From 666e8799251452f74ca97b4a6a930c7b3d0ce553 Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Wed, 10 Apr 2019 17:14:44 -0500 Subject: [PATCH 017/285] Build compiler_rt for WASM exe --- src/link.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/link.cpp b/src/link.cpp index d6093581f7..70f91f2b8e 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1101,6 +1101,16 @@ static void construct_linker_job_wasm(LinkJob *lj) { for (size_t i = 0; i < g->link_objects.length; i += 1) { lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); } + + if (g->out_type == OutTypeExe) { + if (g->libc_link_lib == nullptr) { + Buf *builtin_a_path = build_a(g, "builtin"); + lj->args.append(buf_ptr(builtin_a_path)); + } + + Buf *compiler_rt_o_path = build_compiler_rt(g); + lj->args.append(buf_ptr(compiler_rt_o_path)); + } } static void coff_append_machine_arg(CodeGen *g, ZigList *list) { From 13798d26c769323ab2a7798c27a8c62af32fd60c Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Wed, 10 Apr 2019 19:05:05 -0500 Subject: [PATCH 018/285] pass exec_path to zig run --- src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bd3d574956..85e5b0c042 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1144,14 +1144,15 @@ int main(int argc, char **argv) { codegen_print_timing_report(g, stdout); if (cmd == CmdRun) { + const char *exec_path = buf_ptr(&g->output_file_path); ZigList args = {0}; + + args.append(exec_path); if (runtime_args_start != -1) { for (int i = runtime_args_start; i < argc; ++i) { args.append(argv[i]); } } - - const char *exec_path = buf_ptr(&g->output_file_path); args.append(nullptr); os_execv(exec_path, args.items); From a4c7e4c4eb7b1000252fab3f98f6204edb48a4bd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 10 Apr 2019 22:33:33 -0400 Subject: [PATCH 019/285] __muloti4 does not need the ABI workaround on Windows Fixes 128-bit integer multiplication on Windows. closes #2250 --- std/special/compiler_rt.zig | 3 +-- std/special/compiler_rt/muloti4.zig | 5 ----- test/stage1/behavior/math.zig | 7 +++++++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index 6eb87cbd93..e2ecd1b0cf 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -165,7 +165,6 @@ comptime { @export("__divti3", @import("compiler_rt/divti3.zig").__divti3_windows_x86_64, linkage); @export("__modti3", @import("compiler_rt/modti3.zig").__modti3_windows_x86_64, linkage); @export("__multi3", @import("compiler_rt/multi3.zig").__multi3_windows_x86_64, linkage); - @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4_windows_x86_64, linkage); @export("__udivti3", @import("compiler_rt/udivti3.zig").__udivti3_windows_x86_64, linkage); @export("__udivmodti4", @import("compiler_rt/udivmodti4.zig").__udivmodti4_windows_x86_64, linkage); @export("__umodti3", @import("compiler_rt/umodti3.zig").__umodti3_windows_x86_64, linkage); @@ -176,11 +175,11 @@ comptime { @export("__divti3", @import("compiler_rt/divti3.zig").__divti3, linkage); @export("__modti3", @import("compiler_rt/modti3.zig").__modti3, linkage); @export("__multi3", @import("compiler_rt/multi3.zig").__multi3, linkage); - @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4, linkage); @export("__udivti3", @import("compiler_rt/udivti3.zig").__udivti3, linkage); @export("__udivmodti4", @import("compiler_rt/udivmodti4.zig").__udivmodti4, linkage); @export("__umodti3", @import("compiler_rt/umodti3.zig").__umodti3, linkage); } + @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4, linkage); } const std = @import("std"); diff --git a/std/special/compiler_rt/muloti4.zig b/std/special/compiler_rt/muloti4.zig index 65953f3e1d..ccde8e3e6c 100644 --- a/std/special/compiler_rt/muloti4.zig +++ b/std/special/compiler_rt/muloti4.zig @@ -44,11 +44,6 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 { return r; } -const v128 = @Vector(2, u64); -pub extern fn __muloti4_windows_x86_64(a: v128, b: v128, overflow: *c_int) v128 { - return @bitCast(v128, @inlineCall(__muloti4, @bitCast(i128, a), @bitCast(i128, b), overflow)); -} - test "import muloti4" { _ = @import("muloti4_test.zig"); } diff --git a/test/stage1/behavior/math.zig b/test/stage1/behavior/math.zig index 23dc6d1feb..acbd9209df 100644 --- a/test/stage1/behavior/math.zig +++ b/test/stage1/behavior/math.zig @@ -632,3 +632,10 @@ fn testNanEqNan(comptime F: type) void { expect(!(nan1 < nan2)); expect(!(nan1 <= nan2)); } + +test "128-bit multiplication" { + var a: i128 = 3; + var b: i128 = 2; + var c = a * b; + expect(c == 6); +} From e309ad884a5d2fc8b78325199cd6e81d2efa220d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 10 Apr 2019 22:58:42 -0400 Subject: [PATCH 020/285] fix outdated/incorrect docs for `@truncate` closes #2234 --- doc/langref.html.in | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index 1d80c73a3e..a73e5d94d9 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -7360,20 +7360,30 @@ fn List(comptime T: type) type {
{#syntax#}@truncate(comptime T: type, integer: var) T{#endsyntax#}

This function truncates bits from an integer type, resulting in a smaller - integer type. + or same-sized integer type.

- The following produces a crash in {#link|Debug#} mode and {#link|Undefined Behavior#} in - {#link|ReleaseFast#} mode: + The following produces safety-checked {#link|Undefined Behavior#}:

-
{#syntax#}const a: u16 = 0xabcd;
-const b: u8 = u8(a);{#endsyntax#}
+ {#code_begin|test_err|cast truncated bits#} +test "integer cast panic" { + var a: u16 = 0xabcd; + var b: u8 = @intCast(u8, a); +} + {#code_end#}

However this is well defined and working code:

-
{#syntax#}const a: u16 = 0xabcd;
-const b: u8 = @truncate(u8, a);
-// b is now 0xcd{#endsyntax#}
+ {#code_begin|test|truncate#} +const std = @import("std"); +const assert = std.debug.assert; + +test "integer truncation" { + var a: u16 = 0xabcd; + var b: u8 = @truncate(u8, a); + assert(b == 0xcd); +} + {#code_end#}

This function always truncates the significant bits of the integer, regardless of endianness on the target platform. From ea1d2a240956b2b25d945d361fd274e67ec7849c Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Tue, 26 Mar 2019 19:47:26 +1300 Subject: [PATCH 021/285] Add read-only, non-allocating Int for internal constants A constant Int is one which has a value of null for its allocator field. It cannot be resized or have its limbs written. Any attempt made to write to it will be caught with a runtime panic. --- std/math/big/int.zig | 146 ++++++++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 63 deletions(-) diff --git a/std/math/big/int.zig b/std/math/big/int.zig index 8800c2c7a9..7812d1ee06 100644 --- a/std/math/big/int.zig +++ b/std/math/big/int.zig @@ -22,7 +22,7 @@ comptime { } pub const Int = struct { - allocator: *Allocator, + allocator: ?*Allocator, positive: bool, // - little-endian ordered // - len >= 1 always @@ -55,16 +55,40 @@ pub const Int = struct { }; } + // Initialize an Int directly from a fixed set of limb values. This is considered read-only + // and cannot be used as a receiver argument to any functions. If this tries to allocate + // at any point a panic will occur due to the null allocator. + pub fn initFixed(limbs: []const Limb) Int { + var self = Int{ + .allocator = null, + .positive = true, + // Cast away the const, invalid use to pass as a pointer argument. + .limbs = @intToPtr([*]Limb, @ptrToInt(limbs.ptr))[0..limbs.len], + .len = limbs.len, + }; + + self.normN(limbs.len); + return self; + } + pub fn ensureCapacity(self: *Int, capacity: usize) !void { + self.assertWritable(); if (capacity <= self.limbs.len) { return; } - self.limbs = try self.allocator.realloc(self.limbs, capacity); + self.limbs = try self.allocator.?.realloc(self.limbs, capacity); + } + + fn assertWritable(self: Int) void { + if (self.allocator == null) { + @panic("provided Int value is read-only but must be writable"); + } } pub fn deinit(self: *Int) void { - self.allocator.free(self.limbs); + self.assertWritable(); + self.allocator.?.free(self.limbs); self.* = undefined; } @@ -73,7 +97,7 @@ pub const Int = struct { .allocator = other.allocator, .positive = other.positive, .limbs = block: { - var limbs = try other.allocator.alloc(Limb, other.len); + var limbs = try other.allocator.?.alloc(Limb, other.len); mem.copy(Limb, limbs[0..], other.limbs[0..other.len]); break :block limbs; }, @@ -82,7 +106,8 @@ pub const Int = struct { } pub fn copy(self: *Int, other: Int) !void { - if (self == &other) { + self.assertWritable(); + if (self.limbs.ptr == other.limbs.ptr) { return; } @@ -93,6 +118,7 @@ pub const Int = struct { } pub fn swap(self: *Int, other: *Int) void { + self.assertWritable(); mem.swap(Int, self, other); } @@ -103,20 +129,20 @@ pub const Int = struct { debug.warn("\n"); } - pub fn negate(r: *Int) void { - r.positive = !r.positive; + pub fn negate(self: *Int) void { + self.positive = !self.positive; } - pub fn abs(r: *Int) void { - r.positive = true; + pub fn abs(self: *Int) void { + self.positive = true; } - pub fn isOdd(r: Int) bool { - return r.limbs[0] & 1 != 0; + pub fn isOdd(self: Int) bool { + return self.limbs[0] & 1 != 0; } - pub fn isEven(r: Int) bool { - return !r.isOdd(); + pub fn isEven(self: Int) bool { + return !self.isOdd(); } // Returns the number of bits required to represent the absolute value of self. @@ -179,6 +205,7 @@ pub const Int = struct { } pub fn set(self: *Int, value: var) Allocator.Error!void { + self.assertWritable(); const T = @typeOf(value); switch (@typeInfo(T)) { @@ -304,6 +331,7 @@ pub const Int = struct { } pub fn setString(self: *Int, base: u8, value: []const u8) !void { + self.assertWritable(); if (base < 2 or base > 16) { return error.InvalidBase; } @@ -315,23 +343,16 @@ pub const Int = struct { i += 1; } - // TODO values less than limb size should guarantee non allocating - var base_buffer: [512]u8 = undefined; - const base_al = &std.heap.FixedBufferAllocator.init(base_buffer[0..]).allocator; - const base_ap = try Int.initSet(base_al, base); - - var d_buffer: [512]u8 = undefined; - var d_fba = std.heap.FixedBufferAllocator.init(d_buffer[0..]); - const d_al = &d_fba.allocator; - + const ap_base = Int.initFixed(([]Limb{base})[0..]); try self.set(0); + for (value[i..]) |ch| { const d = try charToDigit(ch, base); - d_fba.end_index = 0; - const d_ap = try Int.initSet(d_al, d); - try self.mul(self.*, base_ap); - try self.add(self.*, d_ap); + const ap_d = Int.initFixed(([]Limb{d})[0..]); + + try self.mul(self.*, ap_base); + try self.add(self.*, ap_d); } self.positive = positive; } @@ -520,8 +541,19 @@ pub const Int = struct { r.len = if (j != 0) j else 1; } + // Cannot be used as a result argument to any function. + fn readOnlyPositive(a: Int) Int { + return Int{ + .allocator = null, + .positive = true, + .limbs = a.limbs, + .len = a.len, + }; + } + // r = a + b pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void { + r.assertWritable(); if (a.eqZero()) { try r.copy(b); return; @@ -533,22 +565,10 @@ pub const Int = struct { if (a.positive != b.positive) { if (a.positive) { // (a) + (-b) => a - b - const bp = Int{ - .allocator = undefined, - .positive = true, - .limbs = b.limbs, - .len = b.len, - }; - try r.sub(a, bp); + try r.sub(a, readOnlyPositive(b)); } else { // (-a) + (b) => b - a - const ap = Int{ - .allocator = undefined, - .positive = true, - .limbs = a.limbs, - .len = a.len, - }; - try r.sub(b, ap); + try r.sub(b, readOnlyPositive(a)); } } else { if (a.len >= b.len) { @@ -591,25 +611,14 @@ pub const Int = struct { // r = a - b pub fn sub(r: *Int, a: Int, b: Int) !void { + r.assertWritable(); if (a.positive != b.positive) { if (a.positive) { // (a) - (-b) => a + b - const bp = Int{ - .allocator = undefined, - .positive = true, - .limbs = b.limbs, - .len = b.len, - }; - try r.add(a, bp); + try r.add(a, readOnlyPositive(b)); } else { // (-a) - (b) => -(a + b) - const ap = Int{ - .allocator = undefined, - .positive = true, - .limbs = a.limbs, - .len = a.len, - }; - try r.add(ap, b); + try r.add(readOnlyPositive(a), b); r.positive = false; } } else { @@ -671,12 +680,14 @@ pub const Int = struct { // // For greatest efficiency, ensure rma does not alias a or b. pub fn mul(rma: *Int, a: Int, b: Int) !void { + rma.assertWritable(); + var r = rma; var aliased = rma.limbs.ptr == a.limbs.ptr or rma.limbs.ptr == b.limbs.ptr; var sr: Int = undefined; if (aliased) { - sr = try Int.initCapacity(rma.allocator, a.len + b.len); + sr = try Int.initCapacity(rma.allocator.?, a.len + b.len); r = &sr; aliased = true; } @@ -745,13 +756,9 @@ pub const Int = struct { // Trunc -> Floor. if (!q.positive) { - // TODO values less than limb size should guarantee non allocating - var one_buffer: [512]u8 = undefined; - const one_al = &std.heap.FixedBufferAllocator.init(one_buffer[0..]).allocator; - const one_ap = try Int.initSet(one_al, 1); - - try q.sub(q.*, one_ap); - try r.add(q.*, one_ap); + const one = Int.initFixed(([]Limb{1})[0..]); + try q.sub(q.*, one); + try r.add(q.*, one); } r.positive = b.positive; } @@ -763,6 +770,9 @@ pub const Int = struct { // Truncates by default. fn div(quo: *Int, rem: *Int, a: Int, b: Int) !void { + quo.assertWritable(); + rem.assertWritable(); + if (b.eqZero()) { @panic("division by zero"); } @@ -800,7 +810,7 @@ pub const Int = struct { // x may grow one limb during normalization try quo.ensureCapacity(a.len + y.len); - try divN(quo.allocator, quo, rem, &x, &y); + try divN(quo.allocator.?, quo, rem, &x, &y); quo.positive = a.positive == b.positive; } @@ -919,6 +929,8 @@ pub const Int = struct { // r = a << shift, in other words, r = a * 2^shift pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void { + r.assertWritable(); + try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1); llshl(r.limbs[0..], a.limbs[0..a.len], shift); r.norm1(a.len + (shift / Limb.bit_count) + 1); @@ -950,6 +962,8 @@ pub const Int = struct { // r = a >> shift pub fn shiftRight(r: *Int, a: Int, shift: usize) !void { + r.assertWritable(); + if (a.len <= shift / Limb.bit_count) { r.len = 1; r.limbs[0] = 0; @@ -985,6 +999,8 @@ pub const Int = struct { // r = a | b pub fn bitOr(r: *Int, a: Int, b: Int) !void { + r.assertWritable(); + if (a.len > b.len) { try r.ensureCapacity(a.len); llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); @@ -1012,6 +1028,8 @@ pub const Int = struct { // r = a & b pub fn bitAnd(r: *Int, a: Int, b: Int) !void { + r.assertWritable(); + if (a.len > b.len) { try r.ensureCapacity(b.len); lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); @@ -1036,6 +1054,8 @@ pub const Int = struct { // r = a ^ b pub fn bitXor(r: *Int, a: Int, b: Int) !void { + r.assertWritable(); + if (a.len > b.len) { try r.ensureCapacity(a.len); llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); From 5f4fcd5030fa93cf2518f98ffc666e4e4dc1052b Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Tue, 26 Mar 2019 19:53:02 +1300 Subject: [PATCH 022/285] Add initial big.Rational type --- CMakeLists.txt | 1 + std/math/big.zig | 2 + std/math/big/rational.zig | 898 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 901 insertions(+) create mode 100644 std/math/big/rational.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 8588c3ae9e..2c34f334f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -521,6 +521,7 @@ set(ZIG_STD_FILES "math/atanh.zig" "math/big.zig" "math/big/int.zig" + "math/big/rational.zig" "math/cbrt.zig" "math/ceil.zig" "math/complex.zig" diff --git a/std/math/big.zig b/std/math/big.zig index 94b6d864e7..44b5ce675f 100644 --- a/std/math/big.zig +++ b/std/math/big.zig @@ -1,5 +1,7 @@ pub use @import("big/int.zig"); +pub use @import("big/rational.zig"); test "math.big" { _ = @import("big/int.zig"); + _ = @import("big/rational.zig"); } diff --git a/std/math/big/rational.zig b/std/math/big/rational.zig new file mode 100644 index 0000000000..188d36d909 --- /dev/null +++ b/std/math/big/rational.zig @@ -0,0 +1,898 @@ +const std = @import("../../std.zig"); +const builtin = @import("builtin"); +const debug = std.debug; +const math = std.math; +const mem = std.mem; +const Allocator = mem.Allocator; +const ArrayList = std.ArrayList; + +const TypeId = builtin.TypeId; + +const bn = @import("int.zig"); +const Limb = bn.Limb; +const DoubleLimb = bn.DoubleLimb; +const Int = bn.Int; + +pub const Rational = struct { + // sign of Rational is a.positive, b.positive is ignored + p: Int, + q: Int, + + pub fn init(a: *Allocator) !Rational { + return Rational{ + .p = try Int.init(a), + .q = try Int.initSet(a, 1), + }; + } + + pub fn deinit(self: *Rational) void { + self.p.deinit(); + self.q.deinit(); + } + + pub fn setInt(self: *Rational, a: var) !void { + try self.p.set(a); + try self.q.set(1); + } + + // TODO: Accept a/b fractions and exponent form + pub fn setFloatString(self: *Rational, str: []const u8) !void { + if (str.len == 0) { + return error.InvalidFloatString; + } + + const State = enum { + Integer, + Fractional, + }; + + var state = State.Integer; + var point: ?usize = null; + + var start: usize = 0; + if (str[0] == '-') { + start += 1; + } + + for (str) |c, i| { + switch (state) { + State.Integer => { + switch (c) { + '.' => { + state = State.Fractional; + point = i; + }, + '0'...'9' => { + // okay + }, + else => { + return error.InvalidFloatString; + }, + } + }, + State.Fractional => { + switch (c) { + '0'...'9' => { + // okay + }, + else => { + return error.InvalidFloatString; + }, + } + }, + } + } + + // TODO: batch the multiplies by 10 + if (point) |i| { + try self.p.setString(10, str[0..i]); + + const base = Int.initFixed(([]Limb{10})[0..]); + + var j: usize = start; + while (j < str.len - i - 1) : (j += 1) { + try self.p.mul(self.p, base); + } + + try self.q.setString(10, str[i + 1 ..]); + try self.p.add(self.p, self.q); + + try self.q.set(1); + var k: usize = i + 1; + while (k < str.len) : (k += 1) { + try self.q.mul(self.q, base); + } + + try self.reduce(); + } else { + try self.p.setString(10, str[0..]); + try self.q.set(1); + } + } + + // Translated from golang.go/src/math/big/rat.go. + pub fn setFloat(self: *Rational, comptime T: type, f: T) !void { + debug.assert(@typeId(T) == builtin.TypeId.Float); + + const UnsignedIntType = @IntType(false, T.bit_count); + const f_bits = @bitCast(UnsignedIntType, f); + + const exponent_bits = math.floatExponentBits(T); + const exponent_bias = (1 << (exponent_bits - 1)) - 1; + const mantissa_bits = math.floatMantissaBits(T); + + const exponent_mask = (1 << exponent_bits) - 1; + const mantissa_mask = (1 << mantissa_bits) - 1; + + var exponent = @intCast(i16, (f_bits >> mantissa_bits) & exponent_mask); + var mantissa = f_bits & mantissa_mask; + + switch (exponent) { + exponent_mask => { + return error.NonFiniteFloat; + }, + 0 => { + // denormal + exponent -= exponent_bias - 1; + }, + else => { + // normal + mantissa |= 1 << mantissa_bits; + exponent -= exponent_bias; + }, + } + + var shift: i16 = mantissa_bits - exponent; + + // factor out powers of two early from rational + while (mantissa & 1 == 0 and shift > 0) { + mantissa >>= 1; + shift -= 1; + } + + try self.p.set(mantissa); + self.p.positive = f >= 0; + + try self.q.set(1); + if (shift >= 0) { + try self.q.shiftLeft(self.q, @intCast(usize, shift)); + } else { + try self.p.shiftLeft(self.p, @intCast(usize, -shift)); + } + + try self.reduce(); + } + + // Translated from golang.go/src/math/big/rat.go. + pub fn toFloat(self: Rational, comptime T: type) !T { + debug.assert(@typeId(T) == builtin.TypeId.Float); + + const fsize = T.bit_count; + const BitReprType = @IntType(false, T.bit_count); + + const msize = math.floatMantissaBits(T); + const msize1 = msize + 1; + const msize2 = msize1 + 1; + + const esize = math.floatExponentBits(T); + const ebias = (1 << (esize - 1)) - 1; + const emin = 1 - ebias; + const emax = ebias; + + if (self.p.eqZero()) { + return 0; + } + + // 1. left-shift a or sub so that a/b is in [1 << msize1, 1 << (msize2 + 1)] + var exp = @intCast(isize, self.p.bitCountTwosComp()) - @intCast(isize, self.q.bitCountTwosComp()); + + var a2 = try self.p.clone(); + defer a2.deinit(); + + var b2 = try self.q.clone(); + defer b2.deinit(); + + const shift = msize2 - exp; + if (shift >= 0) { + try a2.shiftLeft(a2, @intCast(usize, shift)); + } else { + try b2.shiftLeft(b2, @intCast(usize, -shift)); + } + + // 2. compute quotient and remainder + var q = try Int.init(self.p.allocator.?); + defer q.deinit(); + + // unused + var r = try Int.init(self.p.allocator.?); + defer r.deinit(); + + try Int.divTrunc(&q, &r, a2, b2); + + var mantissa = extractLowBits(q, BitReprType); + var have_rem = r.len > 0; + + // 3. q didn't fit in msize2 bits, redo division b2 << 1 + if (mantissa >> msize2 == 1) { + if (mantissa & 1 == 1) { + have_rem = true; + } + mantissa >>= 1; + exp += 1; + } + if (mantissa >> msize1 != 1) { + @panic("unexpected bits in result"); + } + + // 4. Rounding + if (emin - msize <= exp and exp <= emin) { + // denormal + const shift1 = @intCast(math.Log2Int(BitReprType), emin - (exp - 1)); + const lost_bits = mantissa & ((@intCast(BitReprType, 1) << shift1) - 1); + have_rem = have_rem or lost_bits != 0; + mantissa >>= shift1; + exp = 2 - ebias; + } + + // round q using round-half-to-even + var exact = !have_rem; + if (mantissa & 1 != 0) { + exact = false; + if (have_rem or (mantissa & 2 != 0)) { + mantissa += 1; + if (mantissa >= 1 << msize2) { + // 11...1 => 100...0 + mantissa >>= 1; + exp += 1; + } + } + } + mantissa >>= 1; + + const f = math.scalbn(@intToFloat(T, mantissa), @intCast(i32, exp - msize1)); + if (math.isInf(f)) { + exact = false; + } + + return if (self.p.positive) f else -f; + } + + pub fn setRatio(self: *Rational, p: var, q: var) !void { + try self.p.set(p); + try self.q.set(q); + + self.p.positive = (@boolToInt(self.p.positive) ^ @boolToInt(self.q.positive)) == 0; + self.q.positive = true; + try self.reduce(); + + if (self.q.eqZero()) { + @panic("cannot set rational with denominator = 0"); + } + } + + pub fn copyInt(self: *Rational, a: Int) !void { + try self.p.copy(a); + try self.q.set(1); + } + + pub fn copyRatio(self: *Rational, a: Int, b: Int) !void { + try self.p.copy(a); + try self.q.copy(b); + + self.p.positive = (@boolToInt(self.p.positive) ^ @boolToInt(self.q.positive)) == 0; + self.q.positive = true; + try self.reduce(); + } + + pub fn abs(r: *Rational) void { + r.p.abs(); + } + + pub fn negate(r: *Rational) void { + r.p.negate(); + } + + pub fn swap(r: *Rational, other: *Rational) void { + r.p.swap(&other.p); + r.q.swap(&other.q); + } + + pub fn cmp(a: Rational, b: Rational) !i8 { + return cmpInternal(a, b, true); + } + + pub fn cmpAbs(a: Rational, b: Rational) !i8 { + return cmpInternal(a, b, false); + } + + // p/q > x/y iff p*y > x*q + fn cmpInternal(a: Rational, b: Rational, is_abs: bool) !i8 { + // TODO: Would a div compare algorithm of sorts be viable and quicker? Can we avoid + // the memory allocations here? + var q = try Int.init(a.p.allocator.?); + defer q.deinit(); + + var p = try Int.init(b.p.allocator.?); + defer p.deinit(); + + try q.mul(a.p, b.q); + try p.mul(b.p, a.q); + + return if (is_abs) q.cmpAbs(p) else q.cmp(p); + } + + // r/q = ap/aq + bp/bq = (ap*bq + bp*aq) / (aq*bq) + // + // For best performance, rma should not alias a or b. + pub fn add(rma: *Rational, a: Rational, b: Rational) !void { + var r = rma; + var aliased = rma.p.limbs.ptr == a.p.limbs.ptr or rma.p.limbs.ptr == b.p.limbs.ptr; + + var sr: Rational = undefined; + if (aliased) { + sr = try Rational.init(rma.p.allocator.?); + r = &sr; + aliased = true; + } + defer if (aliased) { + rma.swap(r); + r.deinit(); + }; + + try r.p.mul(a.p, b.q); + try r.q.mul(b.p, a.q); + try r.p.add(r.p, r.q); + + try r.q.mul(a.q, b.q); + try r.reduce(); + } + + // r/q = ap/aq - bp/bq = (ap*bq - bp*aq) / (aq*bq) + // + // For best performance, rma should not alias a or b. + pub fn sub(rma: *Rational, a: Rational, b: Rational) !void { + var r = rma; + var aliased = rma.p.limbs.ptr == a.p.limbs.ptr or rma.p.limbs.ptr == b.p.limbs.ptr; + + var sr: Rational = undefined; + if (aliased) { + sr = try Rational.init(rma.p.allocator.?); + r = &sr; + aliased = true; + } + defer if (aliased) { + rma.swap(r); + r.deinit(); + }; + + try r.p.mul(a.p, b.q); + try r.q.mul(b.p, a.q); + try r.p.sub(r.p, r.q); + + try r.q.mul(a.q, b.q); + try r.reduce(); + } + + // r/q = ap/aq * bp/bq = ap*bp / aq*bq + pub fn mul(r: *Rational, a: Rational, b: Rational) !void { + try r.p.mul(a.p, b.p); + try r.q.mul(a.q, b.q); + try r.reduce(); + } + + // r/q = (ap/aq) / (bp/bq) = ap*bq / bp*aq + pub fn div(r: *Rational, a: Rational, b: Rational) !void { + if (b.p.eqZero()) { + @panic("division by zero"); + } + + try r.p.mul(a.p, b.q); + try r.q.mul(b.p, a.q); + try r.reduce(); + } + + // r/q = q/r + pub fn invert(r: *Rational) void { + Int.swap(&r.p, &r.q); + } + + // reduce r/q such that gcd(r, q) = 1 + fn reduce(r: *Rational) !void { + var a = try Int.init(r.p.allocator.?); + defer a.deinit(); + + const sign = r.p.positive; + + r.p.abs(); + try gcd(&a, r.p, r.q); + r.p.positive = sign; + + const one = Int.initFixed(([]Limb{1})[0..]); + if (a.cmp(one) != 0) { + var unused = try Int.init(r.p.allocator.?); + defer unused.deinit(); + + // TODO: divexact would be useful here + // TODO: don't copy r.q for div + try Int.divTrunc(&r.p, &unused, r.p, a); + try Int.divTrunc(&r.q, &unused, r.q, a); + } + } +}; + +var al = debug.global_allocator; + +const SignedDoubleLimb = @IntType(true, DoubleLimb.bit_count); + +fn gcd(rma: *Int, x: Int, y: Int) !void { + var r = rma; + var aliased = rma.limbs.ptr == x.limbs.ptr or rma.limbs.ptr == y.limbs.ptr; + + var sr: Int = undefined; + if (aliased) { + sr = try Int.initCapacity(rma.allocator.?, math.max(x.len, y.len)); + r = &sr; + aliased = true; + } + defer if (aliased) { + rma.swap(r); + r.deinit(); + }; + + if (x.cmp(y) > 0) { + try gcdLehmer(r, x, y); + } else { + try gcdLehmer(r, y, x); + } +} + +// Storage must live for the lifetime of the returned value +fn FixedIntFromSignedDoubleLimb(A: SignedDoubleLimb, storage: []Limb) Int { + std.debug.assert(storage.len >= 2); + + var A_is_positive = A >= 0; + const Au = @intCast(DoubleLimb, if (A < 0) -A else A); + storage[0] = @truncate(Limb, Au); + storage[1] = @truncate(Limb, Au >> Limb.bit_count); + var Ap = Int.initFixed(storage[0..2]); + Ap.positive = A_is_positive; + return Ap; +} + +// Handbook of Applied Cryptography, 14.57 +// +// r = gcd(x, y) where x, y > 0 +fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { + debug.assert(xa.positive and ya.positive); + debug.assert(xa.cmp(ya) >= 0); + + var x = try xa.clone(); + defer x.deinit(); + + var y = try ya.clone(); + defer y.deinit(); + + var T = try Int.init(r.allocator.?); + defer T.deinit(); + + while (y.len > 1) { + debug.assert(x.len >= y.len); + + // chop the leading zeros of the limbs and normalize + const offset = @clz(x.limbs[x.len - 1]); + + var xh: SignedDoubleLimb = math.shl(Limb, x.limbs[x.len - 1], offset) | + math.shr(Limb, x.limbs[x.len - 2], Limb.bit_count - offset); + + var yh: SignedDoubleLimb = if (y.len == x.len) + math.shl(Limb, y.limbs[y.len - 1], offset) | math.shr(Limb, y.limbs[y.len - 2], Limb.bit_count - offset) + else if (y.len == x.len - 1) + math.shr(Limb, y.limbs[y.len - 2], Limb.bit_count - offset) + else + 0; + + var A: SignedDoubleLimb = 1; + var B: SignedDoubleLimb = 0; + var C: SignedDoubleLimb = 0; + var D: SignedDoubleLimb = 1; + + while (yh + C != 0 and yh + D != 0) { + const q = @divFloor(xh + A, yh + C); + const qp = @divFloor(xh + B, yh + D); + if (q != qp) { + break; + } + + var t = A - q * C; + A = C; + C = t; + t = B - q * D; + B = D; + D = t; + + t = xh - q * yh; + xh = yh; + yh = t; + } + + if (B == 0) { + // T = x % y, r is unused + try Int.divTrunc(r, &T, x, y); + debug.assert(T.positive); + + x.swap(&y); + y.swap(&T); + } else { + var storage: [8]Limb = undefined; + const Ap = FixedIntFromSignedDoubleLimb(A, storage[0..2]); + const Bp = FixedIntFromSignedDoubleLimb(B, storage[2..4]); + const Cp = FixedIntFromSignedDoubleLimb(C, storage[4..6]); + const Dp = FixedIntFromSignedDoubleLimb(D, storage[6..8]); + + // T = Ax + By + try r.mul(x, Ap); + try T.mul(y, Bp); + try T.add(r.*, T); + + // u = Cx + Dy, r as u + try x.mul(x, Cp); + try r.mul(y, Dp); + try r.add(x, r.*); + + x.swap(&T); + y.swap(r); + } + } + + // euclidean algorithm + debug.assert(x.cmp(y) >= 0); + + while (!y.eqZero()) { + try Int.divTrunc(&T, r, x, y); + x.swap(&y); + y.swap(r); + } + + r.swap(&x); +} + +test "big.rational gcd non-one small" { + var a = try Int.initSet(al, 17); + var b = try Int.initSet(al, 97); + var r = try Int.init(al); + + try gcd(&r, a, b); + + debug.assert((try r.to(u32)) == 1); +} + +test "big.rational gcd non-one small" { + var a = try Int.initSet(al, 4864); + var b = try Int.initSet(al, 3458); + var r = try Int.init(al); + + try gcd(&r, a, b); + + debug.assert((try r.to(u32)) == 38); +} + +test "big.rational gcd non-one large" { + var a = try Int.initSet(al, 0xffffffffffffffff); + var b = try Int.initSet(al, 0xffffffffffffffff7777); + var r = try Int.init(al); + + try gcd(&r, a, b); + + debug.assert((try r.to(u32)) == 4369); +} + +test "big.rational gcd large multi-limb result" { + var a = try Int.initSet(al, 0x12345678123456781234567812345678123456781234567812345678); + var b = try Int.initSet(al, 0x12345671234567123456712345671234567123456712345671234567); + var r = try Int.init(al); + + try gcd(&r, a, b); + + debug.assert((try r.to(u256)) == 0xf000000ff00000fff0000ffff000fffff00ffffff1); +} + +fn extractLowBits(a: Int, comptime T: type) T { + debug.assert(@typeId(T) == builtin.TypeId.Int); + + if (T.bit_count <= Limb.bit_count) { + return @truncate(T, a.limbs[0]); + } else { + var r: T = 0; + comptime var i: usize = 0; + + // Remainder is always 0 since if T.bit_count >= Limb.bit_count -> Limb | T and both + // are powers of two. + inline while (i < T.bit_count / Limb.bit_count) : (i += 1) { + r |= math.shl(T, a.limbs[i], i * Limb.bit_count); + } + + return r; + } +} + +test "big.rational extractLowBits" { + var a = try Int.initSet(al, 0x11112222333344441234567887654321); + + const a1 = extractLowBits(a, u8); + debug.assert(a1 == 0x21); + + const a2 = extractLowBits(a, u16); + debug.assert(a2 == 0x4321); + + const a3 = extractLowBits(a, u32); + debug.assert(a3 == 0x87654321); + + const a4 = extractLowBits(a, u64); + debug.assert(a4 == 0x1234567887654321); + + const a5 = extractLowBits(a, u128); + debug.assert(a5 == 0x11112222333344441234567887654321); +} + +test "big.rational set" { + var a = try Rational.init(al); + + try a.setInt(5); + debug.assert((try a.p.to(u32)) == 5); + debug.assert((try a.q.to(u32)) == 1); + + try a.setRatio(7, 3); + debug.assert((try a.p.to(u32)) == 7); + debug.assert((try a.q.to(u32)) == 3); + + try a.setRatio(9, 3); + debug.assert((try a.p.to(i32)) == 3); + debug.assert((try a.q.to(i32)) == 1); + + try a.setRatio(-9, 3); + debug.assert((try a.p.to(i32)) == -3); + debug.assert((try a.q.to(i32)) == 1); + + try a.setRatio(9, -3); + debug.assert((try a.p.to(i32)) == -3); + debug.assert((try a.q.to(i32)) == 1); + + try a.setRatio(-9, -3); + debug.assert((try a.p.to(i32)) == 3); + debug.assert((try a.q.to(i32)) == 1); +} + +test "big.rational setFloat" { + var a = try Rational.init(al); + + try a.setFloat(f64, 2.5); + debug.assert((try a.p.to(i32)) == 5); + debug.assert((try a.q.to(i32)) == 2); + + try a.setFloat(f32, -2.5); + debug.assert((try a.p.to(i32)) == -5); + debug.assert((try a.q.to(i32)) == 2); + + try a.setFloat(f32, 3.141593); + + // = 3.14159297943115234375 + debug.assert((try a.p.to(u32)) == 3294199); + debug.assert((try a.q.to(u32)) == 1048576); + + try a.setFloat(f64, 72.141593120712409172417410926841290461290467124); + + // = 72.1415931207124145885245525278151035308837890625 + debug.assert((try a.p.to(u128)) == 5076513310880537); + debug.assert((try a.q.to(u128)) == 70368744177664); +} + +test "big.rational setFloatString" { + var a = try Rational.init(al); + + try a.setFloatString("72.14159312071241458852455252781510353"); + + // = 72.1415931207124145885245525278151035308837890625 + debug.assert((try a.p.to(u128)) == 7214159312071241458852455252781510353); + debug.assert((try a.q.to(u128)) == 100000000000000000000000000000000000); +} + +test "big.rational toFloat" { + var a = try Rational.init(al); + + // = 3.14159297943115234375 + try a.setRatio(3294199, 1048576); + debug.assert((try a.toFloat(f64)) == 3.14159297943115234375); + + // = 72.1415931207124145885245525278151035308837890625 + try a.setRatio(5076513310880537, 70368744177664); + debug.assert((try a.toFloat(f64)) == 72.141593120712409172417410926841290461290467124); +} + +test "big.rational set/to Float round-trip" { + // toFloat allocates memory in a loop so we need to free it + var buf: [512 * 1024]u8 = undefined; + var fixed = std.heap.FixedBufferAllocator.init(buf[0..]); + + var a = try Rational.init(&fixed.allocator); + + var prng = std.rand.DefaultPrng.init(0x5EED); + var i: usize = 0; + while (i < 512) : (i += 1) { + const r = prng.random.float(f64); + try a.setFloat(f64, r); + debug.assert((try a.toFloat(f64)) == r); + } +} + +test "big.rational copy" { + var a = try Rational.init(al); + + const b = try Int.initSet(al, 5); + + try a.copyInt(b); + debug.assert((try a.p.to(u32)) == 5); + debug.assert((try a.q.to(u32)) == 1); + + const c = try Int.initSet(al, 7); + const d = try Int.initSet(al, 3); + + try a.copyRatio(c, d); + debug.assert((try a.p.to(u32)) == 7); + debug.assert((try a.q.to(u32)) == 3); + + const e = try Int.initSet(al, 9); + const f = try Int.initSet(al, 3); + + try a.copyRatio(e, f); + debug.assert((try a.p.to(u32)) == 3); + debug.assert((try a.q.to(u32)) == 1); +} + +test "big.rational negate" { + var a = try Rational.init(al); + + try a.setInt(-50); + debug.assert((try a.p.to(i32)) == -50); + debug.assert((try a.q.to(i32)) == 1); + + a.negate(); + debug.assert((try a.p.to(i32)) == 50); + debug.assert((try a.q.to(i32)) == 1); + + a.negate(); + debug.assert((try a.p.to(i32)) == -50); + debug.assert((try a.q.to(i32)) == 1); +} + +test "big.rational abs" { + var a = try Rational.init(al); + + try a.setInt(-50); + debug.assert((try a.p.to(i32)) == -50); + debug.assert((try a.q.to(i32)) == 1); + + a.abs(); + debug.assert((try a.p.to(i32)) == 50); + debug.assert((try a.q.to(i32)) == 1); + + a.abs(); + debug.assert((try a.p.to(i32)) == 50); + debug.assert((try a.q.to(i32)) == 1); +} + +test "big.rational swap" { + var a = try Rational.init(al); + var b = try Rational.init(al); + + try a.setRatio(50, 23); + try b.setRatio(17, 3); + + debug.assert((try a.p.to(u32)) == 50); + debug.assert((try a.q.to(u32)) == 23); + + debug.assert((try b.p.to(u32)) == 17); + debug.assert((try b.q.to(u32)) == 3); + + a.swap(&b); + + debug.assert((try a.p.to(u32)) == 17); + debug.assert((try a.q.to(u32)) == 3); + + debug.assert((try b.p.to(u32)) == 50); + debug.assert((try b.q.to(u32)) == 23); +} + +test "big.rational cmp" { + var a = try Rational.init(al); + var b = try Rational.init(al); + + try a.setRatio(500, 231); + try b.setRatio(18903, 8584); + debug.assert((try a.cmp(b)) < 0); + + try a.setRatio(890, 10); + try b.setRatio(89, 1); + debug.assert((try a.cmp(b)) == 0); +} + +test "big.rational add single-limb" { + var a = try Rational.init(al); + var b = try Rational.init(al); + + try a.setRatio(500, 231); + try b.setRatio(18903, 8584); + debug.assert((try a.cmp(b)) < 0); + + try a.setRatio(890, 10); + try b.setRatio(89, 1); + debug.assert((try a.cmp(b)) == 0); +} + +test "big.rational add" { + var a = try Rational.init(al); + var b = try Rational.init(al); + var r = try Rational.init(al); + + try a.setRatio(78923, 23341); + try b.setRatio(123097, 12441414); + try a.add(a, b); + + try r.setRatio(984786924199, 290395044174); + debug.assert((try a.cmp(r)) == 0); +} + +test "big.rational sub" { + var a = try Rational.init(al); + var b = try Rational.init(al); + var r = try Rational.init(al); + + try a.setRatio(78923, 23341); + try b.setRatio(123097, 12441414); + try a.sub(a, b); + + try r.setRatio(979040510045, 290395044174); + debug.assert((try a.cmp(r)) == 0); +} + +test "big.rational mul" { + var a = try Rational.init(al); + var b = try Rational.init(al); + var r = try Rational.init(al); + + try a.setRatio(78923, 23341); + try b.setRatio(123097, 12441414); + try a.mul(a, b); + + try r.setRatio(571481443, 17082061422); + debug.assert((try a.cmp(r)) == 0); +} + +test "big.rational div" { + var a = try Rational.init(al); + var b = try Rational.init(al); + var r = try Rational.init(al); + + try a.setRatio(78923, 23341); + try b.setRatio(123097, 12441414); + try a.div(a, b); + + try r.setRatio(75531824394, 221015929); + debug.assert((try a.cmp(r)) == 0); +} + +test "big.rational div" { + var a = try Rational.init(al); + var r = try Rational.init(al); + + try a.setRatio(78923, 23341); + a.invert(); + + try r.setRatio(23341, 78923); + debug.assert((try a.cmp(r)) == 0); + + try a.setRatio(-78923, 23341); + a.invert(); + + try r.setRatio(-23341, 78923); + debug.assert((try a.cmp(r)) == 0); +} From b3ecdfd7bfb9c6b3bd085b489fe20dd0ca1e12d8 Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Tue, 26 Mar 2019 20:31:16 +1300 Subject: [PATCH 023/285] Fix big.Int toString maybe-null allocator --- std/math/big/int.zig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/std/math/big/int.zig b/std/math/big/int.zig index 7812d1ee06..89be663a4a 100644 --- a/std/math/big/int.zig +++ b/std/math/big/int.zig @@ -449,9 +449,11 @@ pub const Int = struct { comptime FmtError: type, output: fn (@typeOf(context), []const u8) FmtError!void, ) FmtError!void { + self.assertWritable(); // TODO look at fmt and support other bases - const str = self.toString(self.allocator, 10) catch @panic("TODO make this non allocating"); - defer self.allocator.free(str); + // TODO support read-only fixed integers + const str = self.toString(self.allocator.?, 10) catch @panic("TODO make this non allocating"); + defer self.allocator.?.free(str); return output(context, str); } From d3e1f323626ba5955aa98628c9c817a19baa35fb Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Wed, 27 Mar 2019 22:28:38 +1300 Subject: [PATCH 024/285] Small fixes for big.Rational and corrections for gcdLehmer The int div code still causes some edge cases to fail right now. --- std/math/big/int.zig | 7 +- std/math/big/rational.zig | 160 ++++++++++++++++++++------------------ 2 files changed, 91 insertions(+), 76 deletions(-) diff --git a/std/math/big/int.zig b/std/math/big/int.zig index 89be663a4a..6f4ce1b54e 100644 --- a/std/math/big/int.zig +++ b/std/math/big/int.zig @@ -93,6 +93,7 @@ pub const Int = struct { } pub fn clone(other: Int) !Int { + other.assertWritable(); return Int{ .allocator = other.allocator, .positive = other.positive, @@ -804,11 +805,13 @@ pub const Int = struct { rem.positive = true; } else { // x and y are modified during division - var x = try a.clone(); + var x = try Int.initCapacity(quo.allocator.?, a.len); defer x.deinit(); + try x.copy(a); - var y = try b.clone(); + var y = try Int.initCapacity(quo.allocator.?, b.len); defer y.deinit(); + try y.copy(b); // x may grow one limb during normalization try quo.ensureCapacity(a.len + y.len); diff --git a/std/math/big/rational.zig b/std/math/big/rational.zig index 188d36d909..ca3b3a5926 100644 --- a/std/math/big/rational.zig +++ b/std/math/big/rational.zig @@ -3,6 +3,7 @@ const builtin = @import("builtin"); const debug = std.debug; const math = std.math; const mem = std.mem; +const testing = std.testing; const Allocator = mem.Allocator; const ArrayList = std.ArrayList; @@ -425,6 +426,7 @@ var al = debug.global_allocator; const SignedDoubleLimb = @IntType(true, DoubleLimb.bit_count); fn gcd(rma: *Int, x: Int, y: Int) !void { + rma.assertWritable(); var r = rma; var aliased = rma.limbs.ptr == x.limbs.ptr or rma.limbs.ptr == y.limbs.ptr; @@ -463,19 +465,23 @@ fn FixedIntFromSignedDoubleLimb(A: SignedDoubleLimb, storage: []Limb) Int { // // r = gcd(x, y) where x, y > 0 fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { - debug.assert(xa.positive and ya.positive); - debug.assert(xa.cmp(ya) >= 0); - var x = try xa.clone(); + x.abs(); defer x.deinit(); var y = try ya.clone(); + y.abs(); defer y.deinit(); + if (x.cmp(y) < 0) { + x.swap(&y); + } + var T = try Int.init(r.allocator.?); defer T.deinit(); while (y.len > 1) { + debug.assert(x.positive and y.positive); debug.assert(x.len >= y.len); // chop the leading zeros of the limbs and normalize @@ -540,7 +546,13 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { try r.add(x, r.*); x.swap(&T); + x.abs(); y.swap(r); + y.abs(); + + if (x.cmp(y) < 0) { + x.swap(&y); + } } } @@ -563,7 +575,7 @@ test "big.rational gcd non-one small" { try gcd(&r, a, b); - debug.assert((try r.to(u32)) == 1); + testing.expect((try r.to(u32)) == 1); } test "big.rational gcd non-one small" { @@ -573,7 +585,7 @@ test "big.rational gcd non-one small" { try gcd(&r, a, b); - debug.assert((try r.to(u32)) == 38); + testing.expect((try r.to(u32)) == 38); } test "big.rational gcd non-one large" { @@ -583,7 +595,7 @@ test "big.rational gcd non-one large" { try gcd(&r, a, b); - debug.assert((try r.to(u32)) == 4369); + testing.expect((try r.to(u32)) == 4369); } test "big.rational gcd large multi-limb result" { @@ -593,11 +605,11 @@ test "big.rational gcd large multi-limb result" { try gcd(&r, a, b); - debug.assert((try r.to(u256)) == 0xf000000ff00000fff0000ffff000fffff00ffffff1); + testing.expect((try r.to(u256)) == 0xf000000ff00000fff0000ffff000fffff00ffffff1); } fn extractLowBits(a: Int, comptime T: type) T { - debug.assert(@typeId(T) == builtin.TypeId.Int); + testing.expect(@typeId(T) == builtin.TypeId.Int); if (T.bit_count <= Limb.bit_count) { return @truncate(T, a.limbs[0]); @@ -619,71 +631,71 @@ test "big.rational extractLowBits" { var a = try Int.initSet(al, 0x11112222333344441234567887654321); const a1 = extractLowBits(a, u8); - debug.assert(a1 == 0x21); + testing.expect(a1 == 0x21); const a2 = extractLowBits(a, u16); - debug.assert(a2 == 0x4321); + testing.expect(a2 == 0x4321); const a3 = extractLowBits(a, u32); - debug.assert(a3 == 0x87654321); + testing.expect(a3 == 0x87654321); const a4 = extractLowBits(a, u64); - debug.assert(a4 == 0x1234567887654321); + testing.expect(a4 == 0x1234567887654321); const a5 = extractLowBits(a, u128); - debug.assert(a5 == 0x11112222333344441234567887654321); + testing.expect(a5 == 0x11112222333344441234567887654321); } test "big.rational set" { var a = try Rational.init(al); try a.setInt(5); - debug.assert((try a.p.to(u32)) == 5); - debug.assert((try a.q.to(u32)) == 1); + testing.expect((try a.p.to(u32)) == 5); + testing.expect((try a.q.to(u32)) == 1); try a.setRatio(7, 3); - debug.assert((try a.p.to(u32)) == 7); - debug.assert((try a.q.to(u32)) == 3); + testing.expect((try a.p.to(u32)) == 7); + testing.expect((try a.q.to(u32)) == 3); try a.setRatio(9, 3); - debug.assert((try a.p.to(i32)) == 3); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == 3); + testing.expect((try a.q.to(i32)) == 1); try a.setRatio(-9, 3); - debug.assert((try a.p.to(i32)) == -3); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == -3); + testing.expect((try a.q.to(i32)) == 1); try a.setRatio(9, -3); - debug.assert((try a.p.to(i32)) == -3); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == -3); + testing.expect((try a.q.to(i32)) == 1); try a.setRatio(-9, -3); - debug.assert((try a.p.to(i32)) == 3); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == 3); + testing.expect((try a.q.to(i32)) == 1); } test "big.rational setFloat" { var a = try Rational.init(al); try a.setFloat(f64, 2.5); - debug.assert((try a.p.to(i32)) == 5); - debug.assert((try a.q.to(i32)) == 2); + testing.expect((try a.p.to(i32)) == 5); + testing.expect((try a.q.to(i32)) == 2); try a.setFloat(f32, -2.5); - debug.assert((try a.p.to(i32)) == -5); - debug.assert((try a.q.to(i32)) == 2); + testing.expect((try a.p.to(i32)) == -5); + testing.expect((try a.q.to(i32)) == 2); try a.setFloat(f32, 3.141593); // = 3.14159297943115234375 - debug.assert((try a.p.to(u32)) == 3294199); - debug.assert((try a.q.to(u32)) == 1048576); + testing.expect((try a.p.to(u32)) == 3294199); + testing.expect((try a.q.to(u32)) == 1048576); try a.setFloat(f64, 72.141593120712409172417410926841290461290467124); // = 72.1415931207124145885245525278151035308837890625 - debug.assert((try a.p.to(u128)) == 5076513310880537); - debug.assert((try a.q.to(u128)) == 70368744177664); + testing.expect((try a.p.to(u128)) == 5076513310880537); + testing.expect((try a.q.to(u128)) == 70368744177664); } test "big.rational setFloatString" { @@ -692,8 +704,8 @@ test "big.rational setFloatString" { try a.setFloatString("72.14159312071241458852455252781510353"); // = 72.1415931207124145885245525278151035308837890625 - debug.assert((try a.p.to(u128)) == 7214159312071241458852455252781510353); - debug.assert((try a.q.to(u128)) == 100000000000000000000000000000000000); + testing.expect((try a.p.to(u128)) == 7214159312071241458852455252781510353); + testing.expect((try a.q.to(u128)) == 100000000000000000000000000000000000); } test "big.rational toFloat" { @@ -701,11 +713,11 @@ test "big.rational toFloat" { // = 3.14159297943115234375 try a.setRatio(3294199, 1048576); - debug.assert((try a.toFloat(f64)) == 3.14159297943115234375); + testing.expect((try a.toFloat(f64)) == 3.14159297943115234375); // = 72.1415931207124145885245525278151035308837890625 try a.setRatio(5076513310880537, 70368744177664); - debug.assert((try a.toFloat(f64)) == 72.141593120712409172417410926841290461290467124); + testing.expect((try a.toFloat(f64)) == 72.141593120712409172417410926841290461290467124); } test "big.rational set/to Float round-trip" { @@ -720,7 +732,7 @@ test "big.rational set/to Float round-trip" { while (i < 512) : (i += 1) { const r = prng.random.float(f64); try a.setFloat(f64, r); - debug.assert((try a.toFloat(f64)) == r); + testing.expect((try a.toFloat(f64)) == r); } } @@ -730,54 +742,54 @@ test "big.rational copy" { const b = try Int.initSet(al, 5); try a.copyInt(b); - debug.assert((try a.p.to(u32)) == 5); - debug.assert((try a.q.to(u32)) == 1); + testing.expect((try a.p.to(u32)) == 5); + testing.expect((try a.q.to(u32)) == 1); const c = try Int.initSet(al, 7); const d = try Int.initSet(al, 3); try a.copyRatio(c, d); - debug.assert((try a.p.to(u32)) == 7); - debug.assert((try a.q.to(u32)) == 3); + testing.expect((try a.p.to(u32)) == 7); + testing.expect((try a.q.to(u32)) == 3); const e = try Int.initSet(al, 9); const f = try Int.initSet(al, 3); try a.copyRatio(e, f); - debug.assert((try a.p.to(u32)) == 3); - debug.assert((try a.q.to(u32)) == 1); + testing.expect((try a.p.to(u32)) == 3); + testing.expect((try a.q.to(u32)) == 1); } test "big.rational negate" { var a = try Rational.init(al); try a.setInt(-50); - debug.assert((try a.p.to(i32)) == -50); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == -50); + testing.expect((try a.q.to(i32)) == 1); a.negate(); - debug.assert((try a.p.to(i32)) == 50); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == 50); + testing.expect((try a.q.to(i32)) == 1); a.negate(); - debug.assert((try a.p.to(i32)) == -50); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == -50); + testing.expect((try a.q.to(i32)) == 1); } test "big.rational abs" { var a = try Rational.init(al); try a.setInt(-50); - debug.assert((try a.p.to(i32)) == -50); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == -50); + testing.expect((try a.q.to(i32)) == 1); a.abs(); - debug.assert((try a.p.to(i32)) == 50); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == 50); + testing.expect((try a.q.to(i32)) == 1); a.abs(); - debug.assert((try a.p.to(i32)) == 50); - debug.assert((try a.q.to(i32)) == 1); + testing.expect((try a.p.to(i32)) == 50); + testing.expect((try a.q.to(i32)) == 1); } test "big.rational swap" { @@ -787,19 +799,19 @@ test "big.rational swap" { try a.setRatio(50, 23); try b.setRatio(17, 3); - debug.assert((try a.p.to(u32)) == 50); - debug.assert((try a.q.to(u32)) == 23); + testing.expect((try a.p.to(u32)) == 50); + testing.expect((try a.q.to(u32)) == 23); - debug.assert((try b.p.to(u32)) == 17); - debug.assert((try b.q.to(u32)) == 3); + testing.expect((try b.p.to(u32)) == 17); + testing.expect((try b.q.to(u32)) == 3); a.swap(&b); - debug.assert((try a.p.to(u32)) == 17); - debug.assert((try a.q.to(u32)) == 3); + testing.expect((try a.p.to(u32)) == 17); + testing.expect((try a.q.to(u32)) == 3); - debug.assert((try b.p.to(u32)) == 50); - debug.assert((try b.q.to(u32)) == 23); + testing.expect((try b.p.to(u32)) == 50); + testing.expect((try b.q.to(u32)) == 23); } test "big.rational cmp" { @@ -808,11 +820,11 @@ test "big.rational cmp" { try a.setRatio(500, 231); try b.setRatio(18903, 8584); - debug.assert((try a.cmp(b)) < 0); + testing.expect((try a.cmp(b)) < 0); try a.setRatio(890, 10); try b.setRatio(89, 1); - debug.assert((try a.cmp(b)) == 0); + testing.expect((try a.cmp(b)) == 0); } test "big.rational add single-limb" { @@ -821,11 +833,11 @@ test "big.rational add single-limb" { try a.setRatio(500, 231); try b.setRatio(18903, 8584); - debug.assert((try a.cmp(b)) < 0); + testing.expect((try a.cmp(b)) < 0); try a.setRatio(890, 10); try b.setRatio(89, 1); - debug.assert((try a.cmp(b)) == 0); + testing.expect((try a.cmp(b)) == 0); } test "big.rational add" { @@ -838,7 +850,7 @@ test "big.rational add" { try a.add(a, b); try r.setRatio(984786924199, 290395044174); - debug.assert((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == 0); } test "big.rational sub" { @@ -851,7 +863,7 @@ test "big.rational sub" { try a.sub(a, b); try r.setRatio(979040510045, 290395044174); - debug.assert((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == 0); } test "big.rational mul" { @@ -864,7 +876,7 @@ test "big.rational mul" { try a.mul(a, b); try r.setRatio(571481443, 17082061422); - debug.assert((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == 0); } test "big.rational div" { @@ -877,7 +889,7 @@ test "big.rational div" { try a.div(a, b); try r.setRatio(75531824394, 221015929); - debug.assert((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == 0); } test "big.rational div" { @@ -888,11 +900,11 @@ test "big.rational div" { a.invert(); try r.setRatio(23341, 78923); - debug.assert((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == 0); try a.setRatio(-78923, 23341); a.invert(); try r.setRatio(-23341, 78923); - debug.assert((try a.cmp(r)) == 0); + testing.expect((try a.cmp(r)) == 0); } From 30788a98b1bb58886d409464baf7eb01e428d939 Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Thu, 28 Mar 2019 20:39:57 +1300 Subject: [PATCH 025/285] Handle zero-limb trailing div case in big.Int --- std/math/big/int.zig | 100 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/std/math/big/int.zig b/std/math/big/int.zig index 6f4ce1b54e..5b84c460da 100644 --- a/std/math/big/int.zig +++ b/std/math/big/int.zig @@ -794,11 +794,30 @@ pub const Int = struct { return; } - if (b.len == 1) { + // Handle trailing zero-words of divisor/dividend. These are not handled in the following + // algorithms. + const a_zero_limb_count = blk: { + var i: usize = 0; + while (i < a.len) : (i += 1) { + if (a.limbs[i] != 0) break; + } + break :blk i; + }; + const b_zero_limb_count = blk: { + var i: usize = 0; + while (i < b.len) : (i += 1) { + if (b.limbs[i] != 0) break; + } + break :blk i; + }; + + const ab_zero_limb_count = std.math.min(a_zero_limb_count, b_zero_limb_count); + + if (b.len - ab_zero_limb_count == 1) { try quo.ensureCapacity(a.len); - lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[0..a.len], b.limbs[0]); - quo.norm1(a.len); + lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[ab_zero_limb_count..a.len], b.limbs[b.len - 1]); + quo.norm1(a.len - ab_zero_limb_count); quo.positive = a.positive == b.positive; rem.len = 1; @@ -815,9 +834,25 @@ pub const Int = struct { // x may grow one limb during normalization try quo.ensureCapacity(a.len + y.len); + + // Shrink x, y such that the trailing zero limbs shared between are removed. + if (ab_zero_limb_count != 0) { + std.mem.copy(Limb, x.limbs[0..], x.limbs[ab_zero_limb_count..]); + std.mem.copy(Limb, y.limbs[0..], y.limbs[ab_zero_limb_count..]); + x.len -= ab_zero_limb_count; + y.len -= ab_zero_limb_count; + } + try divN(quo.allocator.?, quo, rem, &x, &y); quo.positive = a.positive == b.positive; + + // If dividend had trailing zeros beyond divisor, add extra trailing limbs. + // Single-limb division never has multi-limb remainder so nothing to add. + if (a_zero_limb_count > b_zero_limb_count) { + const shift = a_zero_limb_count - b_zero_limb_count; + try rem.shiftLeft(rem.*, shift * Limb.bit_count); + } } } @@ -860,8 +895,11 @@ pub const Int = struct { var tmp = try Int.init(allocator); defer tmp.deinit(); - // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) - const norm_shift = @clz(y.limbs[y.len - 1]); + // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even + var norm_shift = @clz(y.limbs[y.len - 1]); + if (norm_shift == 0 and y.isOdd()) { + norm_shift = Limb.bit_count; + } try x.shiftLeft(x.*, norm_shift); try y.shiftLeft(y.*, norm_shift); @@ -2005,6 +2043,58 @@ test "big.int div multi-multi (3.1/3.3 branch)" { testing.expect((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282); } +test "big.int div multi-single zero-limb trailing" { + var a = try Int.initSet(al, 0x60000000000000000000000000000000000000000000000000000000000000000); + var b = try Int.initSet(al, 0x10000000000000000); + + var q = try Int.init(al); + var r = try Int.init(al); + try Int.divTrunc(&q, &r, a, b); + + var expected = try Int.initSet(al, 0x6000000000000000000000000000000000000000000000000); + testing.expect(q.eq(expected)); + testing.expect(r.eqZero()); +} + +test "big.int div multi-multi zero-limb trailing (with rem)" { + var a = try Int.initSet(al, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000); + var b = try Int.initSet(al, 0x8666666655555555444444443333333300000000000000000000000000000000); + + var q = try Int.init(al); + var r = try Int.init(al); + try Int.divTrunc(&q, &r, a, b); + + testing.expect((try q.to(u128)) == 0x10000000000000000); + testing.expect((try r.to(u128)) == 0x44444443444444431111111111111111); +} + +test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" { + var a = try Int.initSet(al, 0x8666666655555555888888877777777611111111111111110000000000000000); + var b = try Int.initSet(al, 0x8666666655555555444444443333333300000000000000000000000000000000); + + var q = try Int.init(al); + var r = try Int.init(al); + try Int.divTrunc(&q, &r, a, b); + + testing.expect((try q.to(u128)) == 0x1); + testing.expect((try r.to(u128)) == 0x44444443444444431111111111111111); +} + +test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" { + var a = try Int.initSet(al, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000); + var b = try Int.initSet(al, 0x866666665555555544444444333333330000000000000000); + + var q = try Int.init(al); + var r = try Int.init(al); + try Int.divTrunc(&q, &r, a, b); + + const qs = try q.toString(al, 16); + testing.expect(std.mem.eql(u8, qs, "10000000000000000820820803105186f")); + + const rs = try r.toString(al, 16); + testing.expect(std.mem.eql(u8, rs, "4e11f2baa5896a321d463b543d0104e30000000000000000")); +} + test "big.int shift-right single" { var a = try Int.initSet(al, 0xffff0000); try a.shiftRight(a, 16); From 87d8ecda462688c597c726b1da5dbd5f8478e0fc Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Wed, 3 Apr 2019 17:20:23 +1300 Subject: [PATCH 026/285] Fix math.big.Int divN/gcdLehmer and fuzz-test failures --- std/math/big/int.zig | 131 ++++++++++++++++++++++---------------- std/math/big/rational.zig | 53 ++++++--------- 2 files changed, 96 insertions(+), 88 deletions(-) diff --git a/std/math/big/int.zig b/std/math/big/int.zig index 5b84c460da..bd17ed16f7 100644 --- a/std/math/big/int.zig +++ b/std/math/big/int.zig @@ -67,7 +67,7 @@ pub const Int = struct { .len = limbs.len, }; - self.normN(limbs.len); + self.normalize(limbs.len); return self; } @@ -508,28 +508,12 @@ pub const Int = struct { return cmp(a, b) == 0; } - // Normalize for a possible single carry digit. - // - // [1, 2, 3, 4, 0] -> [1, 2, 3, 4] - // [1, 2, 3, 4, 5] -> [1, 2, 3, 4, 5] - // [0] -> [0] - fn norm1(r: *Int, length: usize) void { - debug.assert(length > 0); - debug.assert(length <= r.limbs.len); - - if (r.limbs[length - 1] == 0) { - r.len = if (length > 1) length - 1 else 1; - } else { - r.len = length; - } - } - // Normalize a possible sequence of leading zeros. // // [1, 2, 3, 4, 0] -> [1, 2, 3, 4] // [1, 2, 0, 0, 0] -> [1, 2] // [0, 0, 0, 0, 0] -> [0] - fn normN(r: *Int, length: usize) void { + fn normalize(r: *Int, length: usize) void { debug.assert(length > 0); debug.assert(length <= r.limbs.len); @@ -577,11 +561,11 @@ pub const Int = struct { if (a.len >= b.len) { try r.ensureCapacity(a.len + 1); lladd(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.norm1(a.len + 1); + r.normalize(a.len + 1); } else { try r.ensureCapacity(b.len + 1); lladd(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.norm1(b.len + 1); + r.normalize(b.len + 1); } r.positive = a.positive; @@ -630,12 +614,12 @@ pub const Int = struct { if (a.cmp(b) >= 0) { try r.ensureCapacity(a.len + 1); llsub(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normN(a.len); + r.normalize(a.len); r.positive = true; } else { try r.ensureCapacity(b.len + 1); llsub(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normN(b.len); + r.normalize(b.len); r.positive = false; } } else { @@ -643,12 +627,12 @@ pub const Int = struct { if (a.cmp(b) < 0) { try r.ensureCapacity(a.len + 1); llsub(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normN(a.len); + r.normalize(a.len); r.positive = false; } else { try r.ensureCapacity(b.len + 1); llsub(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normN(b.len); + r.normalize(b.len); r.positive = true; } } @@ -708,7 +692,7 @@ pub const Int = struct { } r.positive = a.positive == b.positive; - r.normN(a.len + b.len); + r.normalize(a.len + b.len); } // a + b * c + *carry, sets carry to the overflow bits @@ -817,7 +801,7 @@ pub const Int = struct { try quo.ensureCapacity(a.len); lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[ab_zero_limb_count..a.len], b.limbs[b.len - 1]); - quo.norm1(a.len - ab_zero_limb_count); + quo.normalize(a.len - ab_zero_limb_count); quo.positive = a.positive == b.positive; rem.len = 1; @@ -846,13 +830,10 @@ pub const Int = struct { try divN(quo.allocator.?, quo, rem, &x, &y); quo.positive = a.positive == b.positive; + } - // If dividend had trailing zeros beyond divisor, add extra trailing limbs. - // Single-limb division never has multi-limb remainder so nothing to add. - if (a_zero_limb_count > b_zero_limb_count) { - const shift = a_zero_limb_count - b_zero_limb_count; - try rem.shiftLeft(rem.*, shift * Limb.bit_count); - } + if (ab_zero_limb_count != 0) { + try rem.shiftLeft(rem.*, ab_zero_limb_count * Limb.bit_count); } } @@ -933,7 +914,7 @@ pub const Int = struct { tmp.limbs[0] = if (i >= 2) x.limbs[i - 2] else 0; tmp.limbs[1] = if (i >= 1) x.limbs[i - 1] else 0; tmp.limbs[2] = x.limbs[i]; - tmp.normN(3); + tmp.normalize(3); while (true) { // 2x1 limb multiplication unrolled against single-limb q[i-t-1] @@ -941,7 +922,7 @@ pub const Int = struct { r.limbs[0] = addMulLimbWithCarry(0, if (t >= 1) y.limbs[t - 1] else 0, q.limbs[i - t - 1], &carry); r.limbs[1] = addMulLimbWithCarry(0, y.limbs[t], q.limbs[i - t - 1], &carry); r.limbs[2] = carry; - r.normN(3); + r.normalize(3); if (r.cmpAbs(tmp) <= 0) { break; @@ -964,10 +945,10 @@ pub const Int = struct { } // Denormalize - q.normN(q.len); + q.normalize(q.len); try r.shiftRight(x.*, norm_shift); - r.normN(r.len); + r.normalize(r.len); } // r = a << shift, in other words, r = a * 2^shift @@ -976,7 +957,7 @@ pub const Int = struct { try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1); llshl(r.limbs[0..], a.limbs[0..a.len], shift); - r.norm1(a.len + (shift / Limb.bit_count) + 1); + r.normalize(a.len + (shift / Limb.bit_count) + 1); r.positive = a.positive; } @@ -1076,11 +1057,11 @@ pub const Int = struct { if (a.len > b.len) { try r.ensureCapacity(b.len); lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normN(b.len); + r.normalize(b.len); } else { try r.ensureCapacity(a.len); lland(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normN(a.len); + r.normalize(a.len); } } @@ -1102,11 +1083,11 @@ pub const Int = struct { if (a.len > b.len) { try r.ensureCapacity(a.len); llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normN(a.len); + r.normalize(a.len); } else { try r.ensureCapacity(b.len); llxor(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normN(b.len); + r.normalize(b.len); } } @@ -1130,7 +1111,9 @@ pub const Int = struct { // They will still run on larger than this and should pass, but the multi-limb code-paths // may be untested in some cases. -const al = debug.global_allocator; +var buffer: [64 * 8192]u8 = undefined; +var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]); +const al = &fixed.allocator; test "big.int comptime_int set" { comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab; @@ -1179,7 +1162,7 @@ test "big.int to target too small error" { testing.expectError(error.TargetTooSmall, a.to(u8)); } -test "big.int norm1" { +test "big.int normalize" { var a = try Int.init(al); try a.ensureCapacity(8); @@ -1187,26 +1170,26 @@ test "big.int norm1" { a.limbs[1] = 2; a.limbs[2] = 3; a.limbs[3] = 0; - a.norm1(4); + a.normalize(4); testing.expect(a.len == 3); a.limbs[0] = 1; a.limbs[1] = 2; a.limbs[2] = 3; - a.norm1(3); + a.normalize(3); testing.expect(a.len == 3); a.limbs[0] = 0; a.limbs[1] = 0; - a.norm1(2); + a.normalize(2); testing.expect(a.len == 1); a.limbs[0] = 0; - a.norm1(1); + a.normalize(1); testing.expect(a.len == 1); } -test "big.int normN" { +test "big.int normalize multi" { var a = try Int.init(al); try a.ensureCapacity(8); @@ -1214,24 +1197,24 @@ test "big.int normN" { a.limbs[1] = 2; a.limbs[2] = 0; a.limbs[3] = 0; - a.normN(4); + a.normalize(4); testing.expect(a.len == 2); a.limbs[0] = 1; a.limbs[1] = 2; a.limbs[2] = 3; - a.normN(3); + a.normalize(3); testing.expect(a.len == 3); a.limbs[0] = 0; a.limbs[1] = 0; a.limbs[2] = 0; a.limbs[3] = 0; - a.normN(4); + a.normalize(4); testing.expect(a.len == 1); a.limbs[0] = 0; - a.normN(1); + a.normalize(1); testing.expect(a.len == 1); } @@ -2065,7 +2048,9 @@ test "big.int div multi-multi zero-limb trailing (with rem)" { try Int.divTrunc(&q, &r, a, b); testing.expect((try q.to(u128)) == 0x10000000000000000); - testing.expect((try r.to(u128)) == 0x44444443444444431111111111111111); + + const rs = try r.toString(al, 16); + testing.expect(std.mem.eql(u8, rs, "4444444344444443111111111111111100000000000000000000000000000000")); } test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" { @@ -2077,7 +2062,9 @@ test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-li try Int.divTrunc(&q, &r, a, b); testing.expect((try q.to(u128)) == 0x1); - testing.expect((try r.to(u128)) == 0x44444443444444431111111111111111); + + const rs = try r.toString(al, 16); + testing.expect(std.mem.eql(u8, rs, "444444434444444311111111111111110000000000000000")); } test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" { @@ -2095,6 +2082,42 @@ test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-li testing.expect(std.mem.eql(u8, rs, "4e11f2baa5896a321d463b543d0104e30000000000000000")); } +test "big.int div multi-multi fuzz case #1" { + var a = try Int.init(al); + var b = try Int.init(al); + + try a.setString(16, "ffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + try b.setString(16, "3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffc000000000000000000000000000000007fffffffffff"); + + var q = try Int.init(al); + var r = try Int.init(al); + try Int.divTrunc(&q, &r, a, b); + + const qs = try q.toString(al, 16); + testing.expect(std.mem.eql(u8, qs, "3ffffffffffffffffffffffffffff0000000000000000000000000000000000001ffffffffffffffffffffffffffff7fffffffe000000000000000000000000000180000000000000000000003fffffbfffffffdfffffffffffffeffff800000100101000000100000000020003fffffdfbfffffe3ffffffffffffeffff7fffc00800a100000017ffe000002000400007efbfff7fe9f00000037ffff3fff7fffa004006100000009ffe00000190038200bf7d2ff7fefe80400060000f7d7f8fbf9401fe38e0403ffc0bdffffa51102c300d7be5ef9df4e5060007b0127ad3fa69f97d0f820b6605ff617ddf7f32ad7a05c0d03f2e7bc78a6000e087a8bbcdc59e07a5a079128a7861f553ddebed7e8e56701756f9ead39b48cd1b0831889ea6ec1fddf643d0565b075ff07e6caea4e2854ec9227fd635ed60a2f5eef2893052ffd54718fa08604acbf6a15e78a467c4a3c53c0278af06c4416573f925491b195e8fd79302cb1aaf7caf4ecfc9aec1254cc969786363ac729f914c6ddcc26738d6b0facd54eba026580aba2eb6482a088b0d224a8852420b91ec1")); + + const rs = try r.toString(al, 16); + testing.expect(std.mem.eql(u8, rs, "310d1d4c414426b4836c2635bad1df3a424e50cbdd167ffccb4dfff57d36b4aae0d6ca0910698220171a0f3373c1060a046c2812f0027e321f72979daa5e7973214170d49e885de0c0ecc167837d44502430674a82522e5df6a0759548052420b91ec1")); +} + +test "big.int div multi-multi fuzz case #2" { + var a = try Int.init(al); + var b = try Int.init(al); + + try a.setString(16, "3ffffffffe00000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000001fffffffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffc000000000000000000000000000000000000000000000000000000000000000"); + try b.setString(16, "ffc0000000000000000000000000000000000000000000000000"); + + var q = try Int.init(al); + var r = try Int.init(al); + try Int.divTrunc(&q, &r, a, b); + + const qs = try q.toString(al, 16); + testing.expect(std.mem.eql(u8, qs, "40100400fe3f8fe3f8fe3f8fe3f8fe3f8fe4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f91e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4992649926499264991e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4792e4b92e4b92e4b92e4b92a4a92a4a92a4")); + + const rs = try r.toString(al, 16); + testing.expect(std.mem.eql(u8, rs, "a900000000000000000000000000000000000000000000000000")); +} + test "big.int shift-right single" { var a = try Int.initSet(al, 0xffff0000); try a.shiftRight(a, 16); diff --git a/std/math/big/rational.zig b/std/math/big/rational.zig index ca3b3a5926..ab356d980f 100644 --- a/std/math/big/rational.zig +++ b/std/math/big/rational.zig @@ -222,6 +222,7 @@ pub const Rational = struct { exp += 1; } if (mantissa >> msize1 != 1) { + // NOTE: This can be hit if the limb size is small (u8/16). @panic("unexpected bits in result"); } @@ -421,8 +422,6 @@ pub const Rational = struct { } }; -var al = debug.global_allocator; - const SignedDoubleLimb = @IntType(true, DoubleLimb.bit_count); fn gcd(rma: *Int, x: Int, y: Int) !void { @@ -441,11 +440,7 @@ fn gcd(rma: *Int, x: Int, y: Int) !void { r.deinit(); }; - if (x.cmp(y) > 0) { - try gcdLehmer(r, x, y); - } else { - try gcdLehmer(r, y, x); - } + try gcdLehmer(r, x, y); } // Storage must live for the lifetime of the returned value @@ -461,9 +456,6 @@ fn FixedIntFromSignedDoubleLimb(A: SignedDoubleLimb, storage: []Limb) Int { return Ap; } -// Handbook of Applied Cryptography, 14.57 -// -// r = gcd(x, y) where x, y > 0 fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { var x = try xa.clone(); x.abs(); @@ -484,18 +476,8 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { debug.assert(x.positive and y.positive); debug.assert(x.len >= y.len); - // chop the leading zeros of the limbs and normalize - const offset = @clz(x.limbs[x.len - 1]); - - var xh: SignedDoubleLimb = math.shl(Limb, x.limbs[x.len - 1], offset) | - math.shr(Limb, x.limbs[x.len - 2], Limb.bit_count - offset); - - var yh: SignedDoubleLimb = if (y.len == x.len) - math.shl(Limb, y.limbs[y.len - 1], offset) | math.shr(Limb, y.limbs[y.len - 2], Limb.bit_count - offset) - else if (y.len == x.len - 1) - math.shr(Limb, y.limbs[y.len - 2], Limb.bit_count - offset) - else - 0; + var xh: SignedDoubleLimb = x.limbs[x.len - 1]; + var yh: SignedDoubleLimb = if (x.len > y.len) 0 else y.limbs[x.len - 1]; var A: SignedDoubleLimb = 1; var B: SignedDoubleLimb = 0; @@ -546,13 +528,7 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { try r.add(x, r.*); x.swap(&T); - x.abs(); y.swap(r); - y.abs(); - - if (x.cmp(y) < 0) { - x.swap(&y); - } } } @@ -568,6 +544,10 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { r.swap(&x); } +var buffer: [64 * 8192]u8 = undefined; +var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]); +var al = &fixed.allocator; + test "big.rational gcd non-one small" { var a = try Int.initSet(al, 17); var b = try Int.initSet(al, 97); @@ -608,6 +588,16 @@ test "big.rational gcd large multi-limb result" { testing.expect((try r.to(u256)) == 0xf000000ff00000fff0000ffff000fffff00ffffff1); } +test "big.rational gcd one large" { + var a = try Int.initSet(al, 1897056385327307); + var b = try Int.initSet(al, 2251799813685248); + var r = try Int.init(al); + + try gcd(&r, a, b); + + testing.expect((try r.to(u64)) == 1); +} + fn extractLowBits(a: Int, comptime T: type) T { testing.expect(@typeId(T) == builtin.TypeId.Int); @@ -721,12 +711,7 @@ test "big.rational toFloat" { } test "big.rational set/to Float round-trip" { - // toFloat allocates memory in a loop so we need to free it - var buf: [512 * 1024]u8 = undefined; - var fixed = std.heap.FixedBufferAllocator.init(buf[0..]); - - var a = try Rational.init(&fixed.allocator); - + var a = try Rational.init(al); var prng = std.rand.DefaultPrng.init(0x5EED); var i: usize = 0; while (i < 512) : (i += 1) { From 78af62a19a87904193c59f46ac554330ba872564 Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Tue, 9 Apr 2019 17:44:49 +1200 Subject: [PATCH 027/285] Pack big.Int sign and length fields This effectively takes one-bit from the length field and uses it as the sign bit. It reduces the size of an Int from 40 bits to 32 bits on a 64-bit arch. This also reduces std.Rational from 80 bits to 64 bits. --- src-self-hosted/value.zig | 8 +- std/math/big/int.zig | 341 ++++++++++++++++++++------------------ std/math/big/rational.zig | 39 ++--- 3 files changed, 203 insertions(+), 185 deletions(-) diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig index d8c0f7b5c8..f1c7fc0b50 100644 --- a/src-self-hosted/value.zig +++ b/src-self-hosted/value.zig @@ -538,21 +538,21 @@ pub const Value = struct { switch (self.base.typ.id) { Type.Id.Int => { const type_ref = try self.base.typ.getLlvmType(ofile.arena, ofile.context); - if (self.big_int.len == 0) { + if (self.big_int.len() == 0) { return llvm.ConstNull(type_ref); } - const unsigned_val = if (self.big_int.len == 1) blk: { + const unsigned_val = if (self.big_int.len() == 1) blk: { break :blk llvm.ConstInt(type_ref, self.big_int.limbs[0], @boolToInt(false)); } else if (@sizeOf(std.math.big.Limb) == @sizeOf(u64)) blk: { break :blk llvm.ConstIntOfArbitraryPrecision( type_ref, - @intCast(c_uint, self.big_int.len), + @intCast(c_uint, self.big_int.len()), @ptrCast([*]u64, self.big_int.limbs.ptr), ); } else { @compileError("std.math.Big.Int.Limb size does not match LLVM"); }; - return if (self.big_int.positive) unsigned_val else llvm.ConstNeg(unsigned_val); + return if (self.big_int.isPositive()) unsigned_val else llvm.ConstNeg(unsigned_val); }, Type.Id.ComptimeInt => unreachable, else => unreachable, diff --git a/std/math/big/int.zig b/std/math/big/int.zig index bd17ed16f7..aced892e18 100644 --- a/std/math/big/int.zig +++ b/std/math/big/int.zig @@ -22,13 +22,18 @@ comptime { } pub const Int = struct { + const sign_bit: usize = 1 << (usize.bit_count - 1); + allocator: ?*Allocator, - positive: bool, // - little-endian ordered // - len >= 1 always // - zero value -> len == 1 with limbs[0] == 0 limbs: []Limb, - len: usize, + // High bit is the sign bit. 1 is negative, 0 positive. + // Remaining bits indicate the number of used limbs. + // + // If Zig gets smarter about packing data, this can be rewritten as a u1 and usize - 1 field. + metadata: usize, const default_capacity = 4; @@ -45,26 +50,45 @@ pub const Int = struct { pub fn initCapacity(allocator: *Allocator, capacity: usize) !Int { return Int{ .allocator = allocator, - .positive = true, + .metadata = 1, .limbs = block: { var limbs = try allocator.alloc(Limb, math.max(default_capacity, capacity)); limbs[0] = 0; break :block limbs; }, - .len = 1, }; } + pub fn len(self: Int) usize { + return self.metadata & ~sign_bit; + } + + pub fn isPositive(self: Int) bool { + return self.metadata & sign_bit == 0; + } + + pub fn setSign(self: *Int, positive: bool) void { + if (positive) { + self.metadata &= ~sign_bit; + } else { + self.metadata |= sign_bit; + } + } + + pub fn setLen(self: *Int, new_len: usize) void { + self.metadata &= sign_bit; + self.metadata |= new_len; + } + // Initialize an Int directly from a fixed set of limb values. This is considered read-only // and cannot be used as a receiver argument to any functions. If this tries to allocate // at any point a panic will occur due to the null allocator. pub fn initFixed(limbs: []const Limb) Int { var self = Int{ .allocator = null, - .positive = true, + .metadata = limbs.len, // Cast away the const, invalid use to pass as a pointer argument. .limbs = @intToPtr([*]Limb, @ptrToInt(limbs.ptr))[0..limbs.len], - .len = limbs.len, }; self.normalize(limbs.len); @@ -96,13 +120,12 @@ pub const Int = struct { other.assertWritable(); return Int{ .allocator = other.allocator, - .positive = other.positive, + .metadata = other.metadata, .limbs = block: { - var limbs = try other.allocator.?.alloc(Limb, other.len); - mem.copy(Limb, limbs[0..], other.limbs[0..other.len]); + var limbs = try other.allocator.?.alloc(Limb, other.len()); + mem.copy(Limb, limbs[0..], other.limbs[0..other.len()]); break :block limbs; }, - .len = other.len, }; } @@ -112,10 +135,9 @@ pub const Int = struct { return; } - self.positive = other.positive; - try self.ensureCapacity(other.len); - mem.copy(Limb, self.limbs[0..], other.limbs[0..other.len]); - self.len = other.len; + try self.ensureCapacity(other.len()); + mem.copy(Limb, self.limbs[0..], other.limbs[0..other.len()]); + self.metadata = other.metadata; } pub fn swap(self: *Int, other: *Int) void { @@ -131,11 +153,11 @@ pub const Int = struct { } pub fn negate(self: *Int) void { - self.positive = !self.positive; + self.metadata ^= sign_bit; } pub fn abs(self: *Int) void { - self.positive = true; + self.metadata &= ~sign_bit; } pub fn isOdd(self: Int) bool { @@ -148,7 +170,7 @@ pub const Int = struct { // Returns the number of bits required to represent the absolute value of self. fn bitCountAbs(self: Int) usize { - return (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1])); + return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len() - 1])); } // Returns the number of bits required to represent the integer in twos-complement form. @@ -164,11 +186,11 @@ pub const Int = struct { // If the entire value has only one bit set (e.g. 0b100000000) then the negation in twos // complement requires one less bit. - if (!self.positive) block: { + if (!self.isPositive()) block: { bits += 1; - if (@popCount(self.limbs[self.len - 1]) == 1) { - for (self.limbs[0 .. self.len - 1]) |limb| { + if (@popCount(self.limbs[self.len() - 1]) == 1) { + for (self.limbs[0 .. self.len() - 1]) |limb| { if (@popCount(limb) != 0) { break :block; } @@ -185,11 +207,11 @@ pub const Int = struct { if (self.eqZero()) { return true; } - if (!is_signed and !self.positive) { + if (!is_signed and !self.isPositive()) { return false; } - const req_bits = self.bitCountTwosComp() + @boolToInt(self.positive and is_signed); + const req_bits = self.bitCountTwosComp() + @boolToInt(self.isPositive() and is_signed); return bit_count >= req_bits; } @@ -201,7 +223,7 @@ pub const Int = struct { // the minus sign. This is used for determining the number of characters needed to print the // value. It is inexact and will exceed the given value by 1-2 digits. pub fn sizeInBase(self: Int, base: usize) usize { - const bit_count = usize(@boolToInt(!self.positive)) + self.bitCountAbs(); + const bit_count = usize(@boolToInt(!self.isPositive())) + self.bitCountAbs(); return (bit_count / math.log2(base)) + 1; } @@ -214,19 +236,19 @@ pub const Int = struct { const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T; try self.ensureCapacity(@sizeOf(UT) / @sizeOf(Limb)); - self.positive = value >= 0; - self.len = 0; + self.metadata = 0; + self.setSign(value >= 0); var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value); if (info.bits <= Limb.bit_count) { self.limbs[0] = Limb(w_value); - self.len = 1; + self.metadata += 1; } else { var i: usize = 0; while (w_value != 0) : (i += 1) { self.limbs[i] = @truncate(Limb, w_value); - self.len += 1; + self.metadata += 1; // TODO: shift == 64 at compile-time fails. Fails on u128 limbs. w_value >>= Limb.bit_count / 2; @@ -240,8 +262,8 @@ pub const Int = struct { const req_limbs = @divFloor(math.log2(w_value), Limb.bit_count) + 1; try self.ensureCapacity(req_limbs); - self.positive = value >= 0; - self.len = req_limbs; + self.metadata = req_limbs; + self.setSign(value >= 0); if (w_value <= maxInt(Limb)) { self.limbs[0] = w_value; @@ -282,17 +304,17 @@ pub const Int = struct { if (@sizeOf(UT) <= @sizeOf(Limb)) { r = @intCast(UT, self.limbs[0]); } else { - for (self.limbs[0..self.len]) |_, ri| { - const limb = self.limbs[self.len - ri - 1]; + for (self.limbs[0..self.len()]) |_, ri| { + const limb = self.limbs[self.len() - ri - 1]; r <<= Limb.bit_count; r |= limb; } } if (!T.is_signed) { - return if (self.positive) @intCast(T, r) else error.NegativeIntoUnsigned; + return if (self.isPositive()) @intCast(T, r) else error.NegativeIntoUnsigned; } else { - if (self.positive) { + if (self.isPositive()) { return @intCast(T, r); } else { if (math.cast(T, r)) |ok| { @@ -355,7 +377,7 @@ pub const Int = struct { try self.mul(self.*, ap_base); try self.add(self.*, ap_d); } - self.positive = positive; + self.setSign(positive); } /// TODO make this call format instead of the other way around @@ -377,7 +399,7 @@ pub const Int = struct { if (base & (base - 1) == 0) { const base_shift = math.log2_int(Limb, base); - for (self.limbs[0..self.len]) |limb| { + for (self.limbs[0..self.len()]) |limb| { var shift: usize = 0; while (shift < Limb.bit_count) : (shift += base_shift) { const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & Limb(base - 1)); @@ -404,11 +426,11 @@ pub const Int = struct { } var q = try self.clone(); - q.positive = true; + q.abs(); var r = try Int.init(allocator); var b = try Int.initSet(allocator, limb_base); - while (q.len >= 2) { + while (q.len() >= 2) { try Int.divTrunc(&q, &r, q, b); var r_word = r.limbs[0]; @@ -421,7 +443,7 @@ pub const Int = struct { } { - debug.assert(q.len == 1); + debug.assert(q.len() == 1); var r_word = q.limbs[0]; while (r_word != 0) { @@ -432,7 +454,7 @@ pub const Int = struct { } } - if (!self.positive) { + if (!self.isPositive()) { try digits.append('-'); } @@ -460,14 +482,14 @@ pub const Int = struct { // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively. pub fn cmpAbs(a: Int, b: Int) i8 { - if (a.len < b.len) { + if (a.len() < b.len()) { return -1; } - if (a.len > b.len) { + if (a.len() > b.len()) { return 1; } - var i: usize = a.len - 1; + var i: usize = a.len() - 1; while (i != 0) : (i -= 1) { if (a.limbs[i] != b.limbs[i]) { break; @@ -485,17 +507,17 @@ pub const Int = struct { // returns -1, 0, 1 if a < b, a == b or a > b respectively. pub fn cmp(a: Int, b: Int) i8 { - if (a.positive != b.positive) { - return if (a.positive) i8(1) else -1; + if (a.isPositive() != b.isPositive()) { + return if (a.isPositive()) i8(1) else -1; } else { const r = cmpAbs(a, b); - return if (a.positive) r else -r; + return if (a.isPositive()) r else -r; } } // if a == 0 pub fn eqZero(a: Int) bool { - return a.len == 1 and a.limbs[0] == 0; + return a.len() == 1 and a.limbs[0] == 0; } // if |a| == |b| @@ -525,16 +547,15 @@ pub const Int = struct { } // Handle zero - r.len = if (j != 0) j else 1; + r.setLen(if (j != 0) j else 1); } // Cannot be used as a result argument to any function. fn readOnlyPositive(a: Int) Int { return Int{ .allocator = null, - .positive = true, + .metadata = a.len(), .limbs = a.limbs, - .len = a.len, }; } @@ -549,8 +570,8 @@ pub const Int = struct { return; } - if (a.positive != b.positive) { - if (a.positive) { + if (a.isPositive() != b.isPositive()) { + if (a.isPositive()) { // (a) + (-b) => a - b try r.sub(a, readOnlyPositive(b)); } else { @@ -558,17 +579,17 @@ pub const Int = struct { try r.sub(b, readOnlyPositive(a)); } } else { - if (a.len >= b.len) { - try r.ensureCapacity(a.len + 1); - lladd(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normalize(a.len + 1); + if (a.len() >= b.len()) { + try r.ensureCapacity(a.len() + 1); + lladd(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); + r.normalize(a.len() + 1); } else { - try r.ensureCapacity(b.len + 1); - lladd(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normalize(b.len + 1); + try r.ensureCapacity(b.len() + 1); + lladd(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]); + r.normalize(b.len() + 1); } - r.positive = a.positive; + r.setSign(a.isPositive()); } } @@ -599,41 +620,41 @@ pub const Int = struct { // r = a - b pub fn sub(r: *Int, a: Int, b: Int) !void { r.assertWritable(); - if (a.positive != b.positive) { - if (a.positive) { + if (a.isPositive() != b.isPositive()) { + if (a.isPositive()) { // (a) - (-b) => a + b try r.add(a, readOnlyPositive(b)); } else { // (-a) - (b) => -(a + b) try r.add(readOnlyPositive(a), b); - r.positive = false; + r.setSign(false); } } else { - if (a.positive) { + if (a.isPositive()) { // (a) - (b) => a - b if (a.cmp(b) >= 0) { - try r.ensureCapacity(a.len + 1); - llsub(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normalize(a.len); - r.positive = true; + try r.ensureCapacity(a.len() + 1); + llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); + r.normalize(a.len()); + r.setSign(true); } else { - try r.ensureCapacity(b.len + 1); - llsub(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normalize(b.len); - r.positive = false; + try r.ensureCapacity(b.len() + 1); + llsub(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]); + r.normalize(b.len()); + r.setSign(false); } } else { // (-a) - (-b) => -(a - b) if (a.cmp(b) < 0) { - try r.ensureCapacity(a.len + 1); - llsub(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normalize(a.len); - r.positive = false; + try r.ensureCapacity(a.len() + 1); + llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); + r.normalize(a.len()); + r.setSign(false); } else { - try r.ensureCapacity(b.len + 1); - llsub(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normalize(b.len); - r.positive = true; + try r.ensureCapacity(b.len() + 1); + llsub(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]); + r.normalize(b.len()); + r.setSign(true); } } } @@ -674,7 +695,7 @@ pub const Int = struct { var sr: Int = undefined; if (aliased) { - sr = try Int.initCapacity(rma.allocator.?, a.len + b.len); + sr = try Int.initCapacity(rma.allocator.?, a.len() + b.len()); r = &sr; aliased = true; } @@ -683,16 +704,16 @@ pub const Int = struct { r.deinit(); }; - try r.ensureCapacity(a.len + b.len); + try r.ensureCapacity(a.len() + b.len()); - if (a.len >= b.len) { - llmul(r.limbs, a.limbs[0..a.len], b.limbs[0..b.len]); + if (a.len() >= b.len()) { + llmul(r.limbs, a.limbs[0..a.len()], b.limbs[0..b.len()]); } else { - llmul(r.limbs, b.limbs[0..b.len], a.limbs[0..a.len]); + llmul(r.limbs, b.limbs[0..b.len()], a.limbs[0..a.len()]); } - r.positive = a.positive == b.positive; - r.normalize(a.len + b.len); + r.normalize(a.len() + b.len()); + r.setSign(a.isPositive() == b.isPositive()); } // a + b * c + *carry, sets carry to the overflow bits @@ -742,17 +763,17 @@ pub const Int = struct { try div(q, r, a, b); // Trunc -> Floor. - if (!q.positive) { + if (!q.isPositive()) { const one = Int.initFixed(([]Limb{1})[0..]); try q.sub(q.*, one); try r.add(q.*, one); } - r.positive = b.positive; + r.setSign(b.isPositive()); } pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void { try div(q, r, a, b); - r.positive = a.positive; + r.setSign(a.isPositive()); } // Truncates by default. @@ -770,10 +791,9 @@ pub const Int = struct { if (a.cmpAbs(b) < 0) { // quo may alias a so handle rem first try rem.copy(a); - rem.positive = a.positive == b.positive; + rem.setSign(a.isPositive() == b.isPositive()); - quo.positive = true; - quo.len = 1; + quo.metadata = 1; quo.limbs[0] = 0; return; } @@ -782,14 +802,14 @@ pub const Int = struct { // algorithms. const a_zero_limb_count = blk: { var i: usize = 0; - while (i < a.len) : (i += 1) { + while (i < a.len()) : (i += 1) { if (a.limbs[i] != 0) break; } break :blk i; }; const b_zero_limb_count = blk: { var i: usize = 0; - while (i < b.len) : (i += 1) { + while (i < b.len()) : (i += 1) { if (b.limbs[i] != 0) break; } break :blk i; @@ -797,39 +817,37 @@ pub const Int = struct { const ab_zero_limb_count = std.math.min(a_zero_limb_count, b_zero_limb_count); - if (b.len - ab_zero_limb_count == 1) { - try quo.ensureCapacity(a.len); + if (b.len() - ab_zero_limb_count == 1) { + try quo.ensureCapacity(a.len()); - lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[ab_zero_limb_count..a.len], b.limbs[b.len - 1]); - quo.normalize(a.len - ab_zero_limb_count); - quo.positive = a.positive == b.positive; + lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[ab_zero_limb_count..a.len()], b.limbs[b.len() - 1]); + quo.normalize(a.len() - ab_zero_limb_count); + quo.setSign(a.isPositive() == b.isPositive()); - rem.len = 1; - rem.positive = true; + rem.metadata = 1; } else { // x and y are modified during division - var x = try Int.initCapacity(quo.allocator.?, a.len); + var x = try Int.initCapacity(quo.allocator.?, a.len()); defer x.deinit(); try x.copy(a); - var y = try Int.initCapacity(quo.allocator.?, b.len); + var y = try Int.initCapacity(quo.allocator.?, b.len()); defer y.deinit(); try y.copy(b); // x may grow one limb during normalization - try quo.ensureCapacity(a.len + y.len); + try quo.ensureCapacity(a.len() + y.len()); // Shrink x, y such that the trailing zero limbs shared between are removed. if (ab_zero_limb_count != 0) { std.mem.copy(Limb, x.limbs[0..], x.limbs[ab_zero_limb_count..]); std.mem.copy(Limb, y.limbs[0..], y.limbs[ab_zero_limb_count..]); - x.len -= ab_zero_limb_count; - y.len -= ab_zero_limb_count; + x.metadata -= ab_zero_limb_count; + y.metadata -= ab_zero_limb_count; } try divN(quo.allocator.?, quo, rem, &x, &y); - - quo.positive = a.positive == b.positive; + quo.setSign(a.isPositive() == b.isPositive()); } if (ab_zero_limb_count != 0) { @@ -868,28 +886,28 @@ pub const Int = struct { // // x = qy + r where 0 <= r < y fn divN(allocator: *Allocator, q: *Int, r: *Int, x: *Int, y: *Int) !void { - debug.assert(y.len >= 2); - debug.assert(x.len >= y.len); - debug.assert(q.limbs.len >= x.len + y.len - 1); + debug.assert(y.len() >= 2); + debug.assert(x.len() >= y.len()); + debug.assert(q.limbs.len >= x.len() + y.len() - 1); debug.assert(default_capacity >= 3); // see 3.2 var tmp = try Int.init(allocator); defer tmp.deinit(); // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even - var norm_shift = @clz(y.limbs[y.len - 1]); + var norm_shift = @clz(y.limbs[y.len() - 1]); if (norm_shift == 0 and y.isOdd()) { norm_shift = Limb.bit_count; } try x.shiftLeft(x.*, norm_shift); try y.shiftLeft(y.*, norm_shift); - const n = x.len - 1; - const t = y.len - 1; + const n = x.len() - 1; + const t = y.len() - 1; // 1. - q.len = n - t + 1; - mem.set(Limb, q.limbs[0..q.len], 0); + q.metadata = n - t + 1; + mem.set(Limb, q.limbs[0..q.len()], 0); // 2. try tmp.shiftLeft(y.*, Limb.bit_count * (n - t)); @@ -937,7 +955,7 @@ pub const Int = struct { try tmp.shiftLeft(tmp, Limb.bit_count * (i - t - 1)); try x.sub(x.*, tmp); - if (!x.positive) { + if (!x.isPositive()) { try tmp.shiftLeft(y.*, Limb.bit_count * (i - t - 1)); try x.add(x.*, tmp); q.limbs[i - t - 1] -= 1; @@ -945,20 +963,20 @@ pub const Int = struct { } // Denormalize - q.normalize(q.len); + q.normalize(q.len()); try r.shiftRight(x.*, norm_shift); - r.normalize(r.len); + r.normalize(r.len()); } // r = a << shift, in other words, r = a * 2^shift pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void { r.assertWritable(); - try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1); - llshl(r.limbs[0..], a.limbs[0..a.len], shift); - r.normalize(a.len + (shift / Limb.bit_count) + 1); - r.positive = a.positive; + try r.ensureCapacity(a.len() + (shift / Limb.bit_count) + 1); + llshl(r.limbs[0..], a.limbs[0..a.len()], shift); + r.normalize(a.len() + (shift / Limb.bit_count) + 1); + r.setSign(a.isPositive()); } fn llshl(r: []Limb, a: []const Limb, shift: usize) void { @@ -988,17 +1006,16 @@ pub const Int = struct { pub fn shiftRight(r: *Int, a: Int, shift: usize) !void { r.assertWritable(); - if (a.len <= shift / Limb.bit_count) { - r.len = 1; + if (a.len() <= shift / Limb.bit_count) { + r.metadata = 1; r.limbs[0] = 0; - r.positive = true; return; } - try r.ensureCapacity(a.len - (shift / Limb.bit_count)); - const r_len = llshr(r.limbs[0..], a.limbs[0..a.len], shift); - r.len = a.len - (shift / Limb.bit_count); - r.positive = a.positive; + try r.ensureCapacity(a.len() - (shift / Limb.bit_count)); + const r_len = llshr(r.limbs[0..], a.limbs[0..a.len()], shift); + r.metadata = a.len() - (shift / Limb.bit_count); + r.setSign(a.isPositive()); } fn llshr(r: []Limb, a: []const Limb, shift: usize) void { @@ -1025,14 +1042,14 @@ pub const Int = struct { pub fn bitOr(r: *Int, a: Int, b: Int) !void { r.assertWritable(); - if (a.len > b.len) { - try r.ensureCapacity(a.len); - llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.len = a.len; + if (a.len() > b.len()) { + try r.ensureCapacity(a.len()); + llor(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); + r.setLen(a.len()); } else { - try r.ensureCapacity(b.len); - llor(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.len = b.len; + try r.ensureCapacity(b.len()); + llor(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]); + r.setLen(b.len()); } } @@ -1054,14 +1071,14 @@ pub const Int = struct { pub fn bitAnd(r: *Int, a: Int, b: Int) !void { r.assertWritable(); - if (a.len > b.len) { - try r.ensureCapacity(b.len); - lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normalize(b.len); + if (a.len() > b.len()) { + try r.ensureCapacity(b.len()); + lland(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); + r.normalize(b.len()); } else { - try r.ensureCapacity(a.len); - lland(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normalize(a.len); + try r.ensureCapacity(a.len()); + lland(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]); + r.normalize(a.len()); } } @@ -1080,14 +1097,14 @@ pub const Int = struct { pub fn bitXor(r: *Int, a: Int, b: Int) !void { r.assertWritable(); - if (a.len > b.len) { - try r.ensureCapacity(a.len); - llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); - r.normalize(a.len); + if (a.len() > b.len()) { + try r.ensureCapacity(a.len()); + llxor(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]); + r.normalize(a.len()); } else { - try r.ensureCapacity(b.len); - llxor(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]); - r.normalize(b.len); + try r.ensureCapacity(b.len()); + llxor(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]); + r.normalize(b.len()); } } @@ -1134,14 +1151,14 @@ test "big.int comptime_int set negative" { var a = try Int.initSet(al, -10); testing.expect(a.limbs[0] == 10); - testing.expect(a.positive == false); + testing.expect(a.isPositive() == false); } test "big.int int set unaligned small" { var a = try Int.initSet(al, u7(45)); testing.expect(a.limbs[0] == 45); - testing.expect(a.positive == true); + testing.expect(a.isPositive() == true); } test "big.int comptime_int to" { @@ -1171,22 +1188,22 @@ test "big.int normalize" { a.limbs[2] = 3; a.limbs[3] = 0; a.normalize(4); - testing.expect(a.len == 3); + testing.expect(a.len() == 3); a.limbs[0] = 1; a.limbs[1] = 2; a.limbs[2] = 3; a.normalize(3); - testing.expect(a.len == 3); + testing.expect(a.len() == 3); a.limbs[0] = 0; a.limbs[1] = 0; a.normalize(2); - testing.expect(a.len == 1); + testing.expect(a.len() == 1); a.limbs[0] = 0; a.normalize(1); - testing.expect(a.len == 1); + testing.expect(a.len() == 1); } test "big.int normalize multi" { @@ -1198,24 +1215,24 @@ test "big.int normalize multi" { a.limbs[2] = 0; a.limbs[3] = 0; a.normalize(4); - testing.expect(a.len == 2); + testing.expect(a.len() == 2); a.limbs[0] = 1; a.limbs[1] = 2; a.limbs[2] = 3; a.normalize(3); - testing.expect(a.len == 3); + testing.expect(a.len() == 3); a.limbs[0] = 0; a.limbs[1] = 0; a.limbs[2] = 0; a.limbs[3] = 0; a.normalize(4); - testing.expect(a.len == 1); + testing.expect(a.len() == 1); a.limbs[0] = 0; a.normalize(1); - testing.expect(a.len == 1); + testing.expect(a.len() == 1); } test "big.int parity" { @@ -1250,7 +1267,7 @@ test "big.int bitcount + sizeInBase" { try a.shiftLeft(a, 5000); testing.expect(a.bitCountAbs() == 5032); testing.expect(a.sizeInBase(2) >= 5032); - a.positive = false; + a.setSign(false); testing.expect(a.bitCountAbs() == 5032); testing.expect(a.sizeInBase(2) >= 5033); diff --git a/std/math/big/rational.zig b/std/math/big/rational.zig index ab356d980f..34cf3bf764 100644 --- a/std/math/big/rational.zig +++ b/std/math/big/rational.zig @@ -15,7 +15,7 @@ const DoubleLimb = bn.DoubleLimb; const Int = bn.Int; pub const Rational = struct { - // sign of Rational is a.positive, b.positive is ignored + // Sign of Rational is sign of p. Sign of q is ignored p: Int, q: Int, @@ -152,7 +152,7 @@ pub const Rational = struct { } try self.p.set(mantissa); - self.p.positive = f >= 0; + self.p.setSign(f >= 0); try self.q.set(1); if (shift >= 0) { @@ -211,7 +211,7 @@ pub const Rational = struct { try Int.divTrunc(&q, &r, a2, b2); var mantissa = extractLowBits(q, BitReprType); - var have_rem = r.len > 0; + var have_rem = r.len() > 0; // 3. q didn't fit in msize2 bits, redo division b2 << 1 if (mantissa >> msize2 == 1) { @@ -256,15 +256,16 @@ pub const Rational = struct { exact = false; } - return if (self.p.positive) f else -f; + return if (self.p.isPositive()) f else -f; } pub fn setRatio(self: *Rational, p: var, q: var) !void { try self.p.set(p); try self.q.set(q); - self.p.positive = (@boolToInt(self.p.positive) ^ @boolToInt(self.q.positive)) == 0; - self.q.positive = true; + self.p.setSign(@boolToInt(self.p.isPositive()) ^ @boolToInt(self.q.isPositive()) == 0); + self.q.setSign(true); + try self.reduce(); if (self.q.eqZero()) { @@ -281,8 +282,9 @@ pub const Rational = struct { try self.p.copy(a); try self.q.copy(b); - self.p.positive = (@boolToInt(self.p.positive) ^ @boolToInt(self.q.positive)) == 0; - self.q.positive = true; + self.p.setSign(@boolToInt(self.p.isPositive()) ^ @boolToInt(self.q.isPositive()) == 0); + self.q.setSign(true); + try self.reduce(); } @@ -403,11 +405,10 @@ pub const Rational = struct { var a = try Int.init(r.p.allocator.?); defer a.deinit(); - const sign = r.p.positive; - + const sign = r.p.isPositive(); r.p.abs(); try gcd(&a, r.p, r.q); - r.p.positive = sign; + r.p.setSign(sign); const one = Int.initFixed(([]Limb{1})[0..]); if (a.cmp(one) != 0) { @@ -431,7 +432,7 @@ fn gcd(rma: *Int, x: Int, y: Int) !void { var sr: Int = undefined; if (aliased) { - sr = try Int.initCapacity(rma.allocator.?, math.max(x.len, y.len)); + sr = try Int.initCapacity(rma.allocator.?, math.max(x.len(), y.len())); r = &sr; aliased = true; } @@ -452,7 +453,7 @@ fn FixedIntFromSignedDoubleLimb(A: SignedDoubleLimb, storage: []Limb) Int { storage[0] = @truncate(Limb, Au); storage[1] = @truncate(Limb, Au >> Limb.bit_count); var Ap = Int.initFixed(storage[0..2]); - Ap.positive = A_is_positive; + Ap.setSign(A_is_positive); return Ap; } @@ -472,12 +473,12 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { var T = try Int.init(r.allocator.?); defer T.deinit(); - while (y.len > 1) { - debug.assert(x.positive and y.positive); - debug.assert(x.len >= y.len); + while (y.len() > 1) { + debug.assert(x.isPositive() and y.isPositive()); + debug.assert(x.len() >= y.len()); - var xh: SignedDoubleLimb = x.limbs[x.len - 1]; - var yh: SignedDoubleLimb = if (x.len > y.len) 0 else y.limbs[x.len - 1]; + var xh: SignedDoubleLimb = x.limbs[x.len() - 1]; + var yh: SignedDoubleLimb = if (x.len() > y.len()) 0 else y.limbs[x.len() - 1]; var A: SignedDoubleLimb = 1; var B: SignedDoubleLimb = 0; @@ -506,7 +507,7 @@ fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void { if (B == 0) { // T = x % y, r is unused try Int.divTrunc(r, &T, x, y); - debug.assert(T.positive); + debug.assert(T.isPositive()); x.swap(&y); y.swap(&T); From 8f5753ba9f1fd43f14628e143d33d6e8a64847f0 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 10 Apr 2019 10:57:43 +0200 Subject: [PATCH 028/285] Fix normalization of right-shifted BigInt at CT The pointer value for the `digits` field was being treated as if it were a limb. Fixes #2225 --- src/bigint.cpp | 11 +++++++++-- test/stage1/behavior/bit_shifting.zig | 8 ++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/bigint.cpp b/src/bigint.cpp index d3178c35c6..dcd9dfc0bd 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -1410,12 +1410,19 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) { } dest->digit_count = op1->digit_count - digit_shift_count; - dest->data.digits = allocate(dest->digit_count); + uint64_t *digits; + if (dest->digit_count == 1) { + digits = &dest->data.digit; + } else { + digits = allocate(dest->digit_count); + dest->data.digits = digits; + } + uint64_t carry = 0; for (size_t op_digit_index = op1->digit_count - 1;;) { uint64_t digit = op1_digits[op_digit_index]; size_t dest_digit_index = op_digit_index - digit_shift_count; - dest->data.digits[dest_digit_index] = carry | (digit >> leftover_shift_count); + digits[dest_digit_index] = carry | (digit >> leftover_shift_count); carry = digit << (64 - leftover_shift_count); if (dest_digit_index == 0) { break; } diff --git a/test/stage1/behavior/bit_shifting.zig b/test/stage1/behavior/bit_shifting.zig index 610acc06c2..c638ec1709 100644 --- a/test/stage1/behavior/bit_shifting.zig +++ b/test/stage1/behavior/bit_shifting.zig @@ -86,3 +86,11 @@ fn testShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, c expect(table.get(@intCast(Key, i)) == node); } } + +// #2225 +test "comptime shr of BigInt" { + comptime { + var n = 0xdeadbeef0000000000000000; + std.debug.assert(n >> 64 == 0xdeadbeef); + } +} From dff201540f91bb41b44d7f73a11f4082f928cff7 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 11 Apr 2019 03:57:53 -0400 Subject: [PATCH 029/285] translate-c: move some code to the C API See #1964 --- src/translate_c.cpp | 778 ++++++++++++++++++++++---------------------- src/zig_clang.cpp | 45 +++ src/zig_clang.h | 15 + 3 files changed, 447 insertions(+), 391 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 8abd66c0ff..5307e3030d 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -112,7 +112,7 @@ static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *paren static TransScopeBlock *trans_scope_block_find(TransScope *scope); -static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_decl); +static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl); static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl); static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl); @@ -122,9 +122,9 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st TransScope **out_node_scope); static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node); static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval); -static AstNode *trans_qual_type(Context *c, clang::QualType qt, const clang::SourceLocation &source_loc); +static AstNode *trans_qual_type(Context *c, clang::QualType qt, ZigClangSourceLocation source_loc); static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval); -static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, const clang::SourceLocation &source_loc); +static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, ZigClangSourceLocation source_loc); static ZigClangSourceLocation bitcast(clang::SourceLocation src) { ZigClangSourceLocation dest; @@ -143,7 +143,7 @@ static clang::QualType bitcast(ZigClangQualType src) { } ATTRIBUTE_PRINTF(3, 4) -static void emit_warning(Context *c, const clang::SourceLocation &clang_sl, const char *format, ...) { +static void emit_warning(Context *c, ZigClangSourceLocation sl, const char *format, ...) { if (!c->warnings_on) { return; } @@ -153,7 +153,6 @@ static void emit_warning(Context *c, const clang::SourceLocation &clang_sl, cons Buf *msg = buf_vprintf(format, ap); va_end(ap); - ZigClangSourceLocation sl = bitcast(clang_sl); const char *filename_bytes = ZigClangSourceManager_getFilename(c->source_manager, ZigClangSourceManager_getSpellingLoc(c->source_manager, sl)); Buf *path; @@ -489,11 +488,6 @@ static Buf *string_ref_to_buf(llvm::StringRef string_ref) { return buf_create_from_mem((const char *)string_ref.bytes_begin(), string_ref.size()); } -static const char *decl_name(const clang::Decl *decl) { - const clang::NamedDecl *named_decl = static_cast(decl); - return (const char *)named_decl->getName().bytes_begin(); -} - static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) { AstNode *node = trans_create_node(c, NodeTypeIntLiteral); node->data.int_literal.bigint = allocate(1); @@ -539,7 +533,7 @@ static clang::QualType get_expr_qual_type_before_implicit_cast(Context *c, const } static AstNode *get_expr_type(Context *c, const clang::Expr *expr) { - return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getBeginLoc()); + return trans_qual_type(c, get_expr_qual_type(c, expr), bitcast(expr->getBeginLoc())); } static bool qual_types_equal(clang::QualType t1, clang::QualType t2) { @@ -598,7 +592,7 @@ static bool qual_type_is_fn_ptr(clang::QualType qt) { return false; } -static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, const clang::SourceLocation &source_loc) { +static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, ZigClangSourceLocation source_loc) { const clang::Type *ty = qt.getTypePtr(); switch (ty->getTypeClass()) { case clang::Type::Builtin: @@ -622,7 +616,7 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, c { const clang::TypedefType *typedef_ty = static_cast(ty); const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); - const char *type_name = decl_name(typedef_decl); + const char *type_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl); if (strcmp(type_name, "uint8_t") == 0 || strcmp(type_name, "int8_t") == 0) { return 8; } else if (strcmp(type_name, "uint16_t") == 0 || strcmp(type_name, "int16_t") == 0) { @@ -643,7 +637,7 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, c static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType &qt, - const clang::SourceLocation &source_loc) + ZigClangSourceLocation source_loc) { uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc); if (int_bit_width != 0) { @@ -688,7 +682,7 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) { return false; } -static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type, +static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, clang::QualType dest_type, clang::QualType src_type, AstNode *expr) { // The only way void pointer casts are valid C code, is if @@ -788,7 +782,7 @@ static bool qual_type_has_wrapping_overflow(Context *c, clang::QualType qt) { } } -static bool type_is_opaque(Context *c, const clang::Type *ty, const clang::SourceLocation &source_loc) { +static bool type_is_opaque(Context *c, const clang::Type *ty, ZigClangSourceLocation source_loc) { switch (ty->getTypeClass()) { case clang::Type::Builtin: { const clang::BuiltinType *builtin_ty = static_cast(ty); @@ -812,7 +806,7 @@ static bool type_is_opaque(Context *c, const clang::Type *ty, const clang::Sourc } } -static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::SourceLocation &source_loc) { +static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLocation source_loc) { switch (ty->getTypeClass()) { case clang::Type::Builtin: { @@ -1129,8 +1123,8 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc } case clang::Type::Record: { - const clang::RecordType *record_ty = static_cast(ty); - return resolve_record_decl(c, record_ty->getDecl()); + const ZigClangRecordType *record_ty = reinterpret_cast(ty); + return resolve_record_decl(c, ZigClangRecordType_getDecl(record_ty)); } case clang::Type::Enum: { @@ -1217,7 +1211,7 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc zig_unreachable(); } -static AstNode *trans_qual_type(Context *c, clang::QualType qt, const clang::SourceLocation &source_loc) { +static AstNode *trans_qual_type(Context *c, clang::QualType qt, ZigClangSourceLocation source_loc) { return trans_type(c, qt.getTypePtr(), source_loc); } @@ -1289,7 +1283,7 @@ static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::Re static AstNode *trans_integer_literal(Context *c, ResultUsed result_used, const clang::IntegerLiteral *stmt) { clang::Expr::EvalResult result; if (!stmt->EvaluateAsInt(result, *reinterpret_cast(c->ctx))) { - emit_warning(c, stmt->getBeginLoc(), "invalid integer literal"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "invalid integer literal"); return nullptr; } AstNode *node = trans_create_node_apint(c, result.Val.getInt()); @@ -1301,10 +1295,10 @@ static AstNode *trans_constant_expr(Context *c, ResultUsed result_used, const cl if (!expr->EvaluateAsConstantExpr(result, clang::Expr::EvaluateForCodeGen, *reinterpret_cast(c->ctx))) { - emit_warning(c, expr->getBeginLoc(), "invalid constant expression"); + emit_warning(c, bitcast(expr->getBeginLoc()), "invalid constant expression"); return nullptr; } - AstNode *node = trans_ap_value(c, &result.Val, expr->getType(), expr->getBeginLoc()); + AstNode *node = trans_ap_value(c, &result.Val, expr->getType(), bitcast(expr->getBeginLoc())); return maybe_suppress_result(c, result_used, node); } @@ -1417,7 +1411,7 @@ static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransSco static AstNode *trans_create_shift_op(Context *c, TransScope *scope, clang::QualType result_type, clang::Expr *lhs_expr, BinOpType bin_op, clang::Expr *rhs_expr) { - const clang::SourceLocation &rhs_location = rhs_expr->getBeginLoc(); + ZigClangSourceLocation rhs_location = bitcast(rhs_expr->getBeginLoc()); AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location); // lhs >> u5(rh) @@ -1434,13 +1428,13 @@ static AstNode *trans_create_shift_op(Context *c, TransScope *scope, clang::Qual static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::BinaryOperator *stmt) { switch (stmt->getOpcode()) { case clang::BO_PtrMemD: - emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_PtrMemD"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_PtrMemD"); return nullptr; case clang::BO_PtrMemI: - emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_PtrMemI"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_PtrMemI"); return nullptr; case clang::BO_Cmp: - emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_Cmp"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_Cmp"); return nullptr; case clang::BO_Mul: { AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), @@ -1584,7 +1578,7 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result_used, TransScope *scope, const clang::CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op) { - const clang::SourceLocation &rhs_location = stmt->getRHS()->getBeginLoc(); + ZigClangSourceLocation rhs_location = bitcast(stmt->getRHS()->getBeginLoc()); AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location); bool use_intermediate_casts = stmt->getComputationLHSType().getTypePtr() != stmt->getComputationResultType().getTypePtr(); @@ -1733,13 +1727,13 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use else return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimes, BinOpTypeMult); case clang::BO_DivAssign: - emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_DivAssign"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_DivAssign"); return nullptr; case clang::BO_RemAssign: - emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_RemAssign"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_RemAssign"); return nullptr; case clang::BO_Cmp: - emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_Cmp"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_Cmp"); return nullptr; case clang::BO_AddAssign: if (qual_type_has_wrapping_overflow(c, stmt->getType())) @@ -1798,7 +1792,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); if (target_node == nullptr) return nullptr; - AstNode *node = trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), + AstNode *node = trans_c_cast(c, bitcast(stmt->getExprLoc()), stmt->getType(), stmt->getSubExpr()->getType(), target_node); return maybe_suppress_result(c, result_used, node); } @@ -1832,160 +1826,160 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra case clang::CK_NoOp: return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); case clang::CK_Dependent: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_Dependent"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_Dependent"); return nullptr; case clang::CK_LValueBitCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_LValueBitCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_LValueBitCast"); return nullptr; case clang::CK_BaseToDerived: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_BaseToDerived"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_BaseToDerived"); return nullptr; case clang::CK_DerivedToBase: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_DerivedToBase"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_DerivedToBase"); return nullptr; case clang::CK_UncheckedDerivedToBase: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_UncheckedDerivedToBase"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_UncheckedDerivedToBase"); return nullptr; case clang::CK_Dynamic: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_Dynamic"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_Dynamic"); return nullptr; case clang::CK_ToUnion: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_ToUnion"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_ToUnion"); return nullptr; case clang::CK_NullToMemberPointer: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_NullToMemberPointer"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_NullToMemberPointer"); return nullptr; case clang::CK_BaseToDerivedMemberPointer: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_BaseToDerivedMemberPointer"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_BaseToDerivedMemberPointer"); return nullptr; case clang::CK_DerivedToBaseMemberPointer: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_DerivedToBaseMemberPointer"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_DerivedToBaseMemberPointer"); return nullptr; case clang::CK_MemberPointerToBoolean: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_MemberPointerToBoolean"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_MemberPointerToBoolean"); return nullptr; case clang::CK_ReinterpretMemberPointer: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_ReinterpretMemberPointer"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_ReinterpretMemberPointer"); return nullptr; case clang::CK_UserDefinedConversion: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_UserDefinedConversion"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_UserDefinedConversion"); return nullptr; case clang::CK_ConstructorConversion: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ConstructorConversion"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ConstructorConversion"); return nullptr; case clang::CK_IntegralToPointer: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToPointer"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToPointer"); return nullptr; case clang::CK_PointerToIntegral: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_PointerToIntegral"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_PointerToIntegral"); return nullptr; case clang::CK_PointerToBoolean: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_PointerToBoolean"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_PointerToBoolean"); return nullptr; case clang::CK_ToVoid: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ToVoid"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ToVoid"); return nullptr; case clang::CK_VectorSplat: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_VectorSplat"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_VectorSplat"); return nullptr; case clang::CK_IntegralToBoolean: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToBoolean"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToBoolean"); return nullptr; case clang::CK_IntegralToFloating: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToFloating"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToFloating"); return nullptr; case clang::CK_FixedPointCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FixedPointCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointCast"); return nullptr; case clang::CK_FixedPointToBoolean: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FixedPointToBoolean"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointToBoolean"); return nullptr; case clang::CK_FloatingToIntegral: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingToIntegral"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingToIntegral"); return nullptr; case clang::CK_FloatingToBoolean: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingToBoolean"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingToBoolean"); return nullptr; case clang::CK_BooleanToSignedIntegral: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BooleanToSignedIntegral"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BooleanToSignedIntegral"); return nullptr; case clang::CK_FloatingCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingCast"); return nullptr; case clang::CK_CPointerToObjCPointerCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_CPointerToObjCPointerCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_CPointerToObjCPointerCast"); return nullptr; case clang::CK_BlockPointerToObjCPointerCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BlockPointerToObjCPointerCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BlockPointerToObjCPointerCast"); return nullptr; case clang::CK_AnyPointerToBlockPointerCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AnyPointerToBlockPointerCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AnyPointerToBlockPointerCast"); return nullptr; case clang::CK_ObjCObjectLValueCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ObjCObjectLValueCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ObjCObjectLValueCast"); return nullptr; case clang::CK_FloatingRealToComplex: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingRealToComplex"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingRealToComplex"); return nullptr; case clang::CK_FloatingComplexToReal: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToReal"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToReal"); return nullptr; case clang::CK_FloatingComplexToBoolean: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToBoolean"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToBoolean"); return nullptr; case clang::CK_FloatingComplexCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexCast"); return nullptr; case clang::CK_FloatingComplexToIntegralComplex: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToIntegralComplex"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToIntegralComplex"); return nullptr; case clang::CK_IntegralRealToComplex: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralRealToComplex"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralRealToComplex"); return nullptr; case clang::CK_IntegralComplexToReal: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToReal"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToReal"); return nullptr; case clang::CK_IntegralComplexToBoolean: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToBoolean"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToBoolean"); return nullptr; case clang::CK_IntegralComplexCast: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexCast"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexCast"); return nullptr; case clang::CK_IntegralComplexToFloatingComplex: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToFloatingComplex"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToFloatingComplex"); return nullptr; case clang::CK_ARCProduceObject: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCProduceObject"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCProduceObject"); return nullptr; case clang::CK_ARCConsumeObject: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCConsumeObject"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCConsumeObject"); return nullptr; case clang::CK_ARCReclaimReturnedObject: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCReclaimReturnedObject"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCReclaimReturnedObject"); return nullptr; case clang::CK_ARCExtendBlockObject: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCExtendBlockObject"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCExtendBlockObject"); return nullptr; case clang::CK_AtomicToNonAtomic: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AtomicToNonAtomic"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AtomicToNonAtomic"); return nullptr; case clang::CK_NonAtomicToAtomic: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_NonAtomicToAtomic"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_NonAtomicToAtomic"); return nullptr; case clang::CK_CopyAndAutoreleaseBlockObject: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_CopyAndAutoreleaseBlockObject"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_CopyAndAutoreleaseBlockObject"); return nullptr; case clang::CK_BuiltinFnToFnPtr: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BuiltinFnToFnPtr"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BuiltinFnToFnPtr"); return nullptr; case clang::CK_ZeroToOCLOpaqueType: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ZeroToOCLOpaqueType"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ZeroToOCLOpaqueType"); return nullptr; case clang::CK_AddressSpaceConversion: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AddressSpaceConversion"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AddressSpaceConversion"); return nullptr; case clang::CK_IntToOCLSampler: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntToOCLSampler"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntToOCLSampler"); return nullptr; } zig_unreachable(); @@ -1993,7 +1987,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const clang::DeclRefExpr *stmt, TransLRValue lrval) { const clang::ValueDecl *value_decl = stmt->getDecl(); - Buf *c_symbol_name = buf_create_from_str(decl_name(value_decl)); + Buf *c_symbol_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)value_decl)); Buf *zig_symbol_name = trans_lookup_zig_symbol(c, scope, c_symbol_name); if (lrval == TransLValue) { c->ptr_params.put(zig_symbol_name, true); @@ -2148,7 +2142,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc return trans_create_node_ptr_deref(c, unwrapped); } case clang::UO_Plus: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Plus"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Plus"); return nullptr; case clang::UO_Minus: { @@ -2174,7 +2168,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc node->data.bin_op_expr.bin_op = BinOpTypeSubWrap; return node; } else { - emit_warning(c, stmt->getBeginLoc(), "C negation with non float non integer"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "C negation with non float non integer"); return nullptr; } } @@ -2197,15 +2191,15 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc return trans_create_node_prefix_op(c, PrefixOpBoolNot, sub_node); } case clang::UO_Real: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Real"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Real"); return nullptr; case clang::UO_Imag: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Imag"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Imag"); return nullptr; case clang::UO_Extension: return trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue); case clang::UO_Coawait: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Coawait"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Coawait"); return nullptr; } zig_unreachable(); @@ -2235,11 +2229,11 @@ static int trans_local_declaration(Context *c, TransScope *scope, const clang::D } else { init_node = trans_create_node(c, NodeTypeUndefinedLiteral); } - AstNode *type_node = trans_qual_type(c, qual_type, stmt->getBeginLoc()); + AstNode *type_node = trans_qual_type(c, qual_type, bitcast(stmt->getBeginLoc())); if (type_node == nullptr) return ErrorUnexpected; - Buf *c_symbol_name = buf_create_from_str(decl_name(var_decl)); + Buf *c_symbol_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl)); TransScopeVar *var_scope = trans_scope_var_create(c, scope, c_symbol_name); scope = &var_scope->base; @@ -2251,223 +2245,223 @@ static int trans_local_declaration(Context *c, TransScope *scope, const clang::D continue; } case clang::Decl::AccessSpec: - emit_warning(c, stmt->getBeginLoc(), "TODO handle decl kind AccessSpec"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle decl kind AccessSpec"); return ErrorUnexpected; case clang::Decl::Block: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Block"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Block"); return ErrorUnexpected; case clang::Decl::Captured: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Captured"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Captured"); return ErrorUnexpected; case clang::Decl::ClassScopeFunctionSpecialization: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassScopeFunctionSpecialization"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassScopeFunctionSpecialization"); return ErrorUnexpected; case clang::Decl::Empty: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Empty"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Empty"); return ErrorUnexpected; case clang::Decl::Export: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Export"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Export"); return ErrorUnexpected; case clang::Decl::ExternCContext: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExternCContext"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExternCContext"); return ErrorUnexpected; case clang::Decl::FileScopeAsm: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C FileScopeAsm"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FileScopeAsm"); return ErrorUnexpected; case clang::Decl::Friend: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Friend"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Friend"); return ErrorUnexpected; case clang::Decl::FriendTemplate: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C FriendTemplate"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FriendTemplate"); return ErrorUnexpected; case clang::Decl::Import: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Import"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Import"); return ErrorUnexpected; case clang::Decl::LinkageSpec: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C LinkageSpec"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LinkageSpec"); return ErrorUnexpected; case clang::Decl::Label: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Label"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Label"); return ErrorUnexpected; case clang::Decl::Namespace: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Namespace"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Namespace"); return ErrorUnexpected; case clang::Decl::NamespaceAlias: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C NamespaceAlias"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NamespaceAlias"); return ErrorUnexpected; case clang::Decl::ObjCCompatibleAlias: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCompatibleAlias"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCompatibleAlias"); return ErrorUnexpected; case clang::Decl::ObjCCategory: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCategory"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCategory"); return ErrorUnexpected; case clang::Decl::ObjCCategoryImpl: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCategoryImpl"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCategoryImpl"); return ErrorUnexpected; case clang::Decl::ObjCImplementation: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCImplementation"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCImplementation"); return ErrorUnexpected; case clang::Decl::ObjCInterface: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCInterface"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCInterface"); return ErrorUnexpected; case clang::Decl::ObjCProtocol: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProtocol"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProtocol"); return ErrorUnexpected; case clang::Decl::ObjCMethod: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCMethod"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCMethod"); return ErrorUnexpected; case clang::Decl::ObjCProperty: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProperty"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProperty"); return ErrorUnexpected; case clang::Decl::BuiltinTemplate: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C BuiltinTemplate"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BuiltinTemplate"); return ErrorUnexpected; case clang::Decl::ClassTemplate: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplate"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplate"); return ErrorUnexpected; case clang::Decl::FunctionTemplate: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C FunctionTemplate"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FunctionTemplate"); return ErrorUnexpected; case clang::Decl::TypeAliasTemplate: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeAliasTemplate"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeAliasTemplate"); return ErrorUnexpected; case clang::Decl::VarTemplate: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplate"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplate"); return ErrorUnexpected; case clang::Decl::TemplateTemplateParm: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C TemplateTemplateParm"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TemplateTemplateParm"); return ErrorUnexpected; case clang::Decl::Enum: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Enum"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Enum"); return ErrorUnexpected; case clang::Decl::Record: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Record"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Record"); return ErrorUnexpected; case clang::Decl::CXXRecord: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXRecord"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXRecord"); return ErrorUnexpected; case clang::Decl::ClassTemplateSpecialization: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplateSpecialization"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplateSpecialization"); return ErrorUnexpected; case clang::Decl::ClassTemplatePartialSpecialization: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplatePartialSpecialization"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplatePartialSpecialization"); return ErrorUnexpected; case clang::Decl::TemplateTypeParm: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C TemplateTypeParm"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TemplateTypeParm"); return ErrorUnexpected; case clang::Decl::ObjCTypeParam: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCTypeParam"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCTypeParam"); return ErrorUnexpected; case clang::Decl::TypeAlias: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeAlias"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeAlias"); return ErrorUnexpected; case clang::Decl::Typedef: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Typedef"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Typedef"); return ErrorUnexpected; case clang::Decl::UnresolvedUsingTypename: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedUsingTypename"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedUsingTypename"); return ErrorUnexpected; case clang::Decl::Using: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Using"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Using"); return ErrorUnexpected; case clang::Decl::UsingDirective: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingDirective"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingDirective"); return ErrorUnexpected; case clang::Decl::UsingPack: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingPack"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingPack"); return ErrorUnexpected; case clang::Decl::UsingShadow: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingShadow"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingShadow"); return ErrorUnexpected; case clang::Decl::ConstructorUsingShadow: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ConstructorUsingShadow"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ConstructorUsingShadow"); return ErrorUnexpected; case clang::Decl::Binding: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Binding"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Binding"); return ErrorUnexpected; case clang::Decl::Field: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Field"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Field"); return ErrorUnexpected; case clang::Decl::ObjCAtDefsField: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtDefsField"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtDefsField"); return ErrorUnexpected; case clang::Decl::ObjCIvar: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIvar"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIvar"); return ErrorUnexpected; case clang::Decl::Function: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Function"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Function"); return ErrorUnexpected; case clang::Decl::CXXDeductionGuide: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDeductionGuide"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDeductionGuide"); return ErrorUnexpected; case clang::Decl::CXXMethod: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXMethod"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXMethod"); return ErrorUnexpected; case clang::Decl::CXXConstructor: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstructor"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstructor"); return ErrorUnexpected; case clang::Decl::CXXConversion: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConversion"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConversion"); return ErrorUnexpected; case clang::Decl::CXXDestructor: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDestructor"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDestructor"); return ErrorUnexpected; case clang::Decl::MSProperty: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSProperty"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSProperty"); return ErrorUnexpected; case clang::Decl::NonTypeTemplateParm: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C NonTypeTemplateParm"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NonTypeTemplateParm"); return ErrorUnexpected; case clang::Decl::Decomposition: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C Decomposition"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Decomposition"); return ErrorUnexpected; case clang::Decl::ImplicitParam: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImplicitParam"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImplicitParam"); return ErrorUnexpected; case clang::Decl::OMPCapturedExpr: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCapturedExpr"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCapturedExpr"); return ErrorUnexpected; case clang::Decl::ParmVar: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ParmVar"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ParmVar"); return ErrorUnexpected; case clang::Decl::VarTemplateSpecialization: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplateSpecialization"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplateSpecialization"); return ErrorUnexpected; case clang::Decl::VarTemplatePartialSpecialization: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplatePartialSpecialization"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplatePartialSpecialization"); return ErrorUnexpected; case clang::Decl::EnumConstant: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C EnumConstant"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C EnumConstant"); return ErrorUnexpected; case clang::Decl::IndirectField: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C IndirectField"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C IndirectField"); return ErrorUnexpected; case clang::Decl::OMPDeclareReduction: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDeclareReduction"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDeclareReduction"); return ErrorUnexpected; case clang::Decl::UnresolvedUsingValue: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedUsingValue"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedUsingValue"); return ErrorUnexpected; case clang::Decl::OMPRequires: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPRequires"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPRequires"); return ErrorUnexpected; case clang::Decl::OMPThreadPrivate: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPThreadPrivate"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPThreadPrivate"); return ErrorUnexpected; case clang::Decl::ObjCPropertyImpl: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCPropertyImpl"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCPropertyImpl"); return ErrorUnexpected; case clang::Decl::PragmaComment: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C PragmaComment"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PragmaComment"); return ErrorUnexpected; case clang::Decl::PragmaDetectMismatch: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C PragmaDetectMismatch"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PragmaDetectMismatch"); return ErrorUnexpected; case clang::Decl::StaticAssert: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C StaticAssert"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C StaticAssert"); return ErrorUnexpected; case clang::Decl::TranslationUnit: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C TranslationUnit"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TranslationUnit"); return ErrorUnexpected; } zig_unreachable(); @@ -2689,7 +2683,7 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope * const clang::ElaboratedType *elaborated_ty = static_cast(ty); switch (elaborated_ty->getKeyword()) { case clang::ETK_Enum: { - AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), expr->getBeginLoc()); + AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), bitcast(expr->getBeginLoc())); return to_enum_zero_cmp(c, res, enum_type); } case clang::ETK_Struct: @@ -2846,7 +2840,7 @@ static AstNode *trans_member_expr(Context *c, ResultUsed result_used, TransScope container_node = trans_create_node_unwrap_null(c, container_node); } - const char *name = decl_name(stmt->getMemberDecl()); + const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)stmt->getMemberDecl()); AstNode *node = trans_create_node_field_access_str(c, container_node, name); return maybe_suppress_result(c, result_used, node); @@ -2875,7 +2869,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran if (sub_expr_node == nullptr) return nullptr; - AstNode *cast = trans_c_cast(c, stmt->getBeginLoc(), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node); + AstNode *cast = trans_c_cast(c, bitcast(stmt->getBeginLoc()), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node); if (cast == nullptr) return nullptr; @@ -2885,7 +2879,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::UnaryExprOrTypeTraitExpr *stmt) { - AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getBeginLoc()); + AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), bitcast(stmt->getBeginLoc())); if (type_node == nullptr) return nullptr; @@ -3092,7 +3086,7 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const clang:: *out_node = nullptr; if (stmt->getRHS() != nullptr) { - emit_warning(c, stmt->getBeginLoc(), "TODO support GNU switch case a ... b extension"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support GNU switch case a ... b extension"); return ErrorUnexpected; } @@ -3177,13 +3171,13 @@ static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransSc return maybe_suppress_result(c, result_used, node); } case clang::StringLiteral::UTF16: - emit_warning(c, stmt->getBeginLoc(), "TODO support UTF16 string literals"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF16 string literals"); return nullptr; case clang::StringLiteral::UTF32: - emit_warning(c, stmt->getBeginLoc(), "TODO support UTF32 string literals"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF32 string literals"); return nullptr; case clang::StringLiteral::Wide: - emit_warning(c, stmt->getBeginLoc(), "TODO support wide string literals"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support wide string literals"); return nullptr; } zig_unreachable(); @@ -3328,505 +3322,505 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st return wrap_stmt(out_node, out_child_scope, scope, trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope)); case clang::Stmt::NoStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C NoStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NoStmtClass"); return ErrorUnexpected; case clang::Stmt::GCCAsmStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C GCCAsmStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GCCAsmStmtClass"); return ErrorUnexpected; case clang::Stmt::MSAsmStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSAsmStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSAsmStmtClass"); return ErrorUnexpected; case clang::Stmt::AttributedStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C AttributedStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AttributedStmtClass"); return ErrorUnexpected; case clang::Stmt::CXXCatchStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXCatchStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXCatchStmtClass"); return ErrorUnexpected; case clang::Stmt::CXXForRangeStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXForRangeStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXForRangeStmtClass"); return ErrorUnexpected; case clang::Stmt::CXXTryStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTryStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTryStmtClass"); return ErrorUnexpected; case clang::Stmt::CapturedStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CapturedStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CapturedStmtClass"); return ErrorUnexpected; case clang::Stmt::CoreturnStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoreturnStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoreturnStmtClass"); return ErrorUnexpected; case clang::Stmt::CoroutineBodyStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoroutineBodyStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoroutineBodyStmtClass"); return ErrorUnexpected; case clang::Stmt::BinaryConditionalOperatorClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C BinaryConditionalOperatorClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BinaryConditionalOperatorClass"); return ErrorUnexpected; case clang::Stmt::AddrLabelExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C AddrLabelExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AddrLabelExprClass"); return ErrorUnexpected; case clang::Stmt::ArrayInitIndexExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayInitIndexExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayInitIndexExprClass"); return ErrorUnexpected; case clang::Stmt::ArrayInitLoopExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayInitLoopExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayInitLoopExprClass"); return ErrorUnexpected; case clang::Stmt::ArrayTypeTraitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayTypeTraitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayTypeTraitExprClass"); return ErrorUnexpected; case clang::Stmt::AsTypeExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C AsTypeExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AsTypeExprClass"); return ErrorUnexpected; case clang::Stmt::AtomicExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C AtomicExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AtomicExprClass"); return ErrorUnexpected; case clang::Stmt::BlockExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C BlockExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BlockExprClass"); return ErrorUnexpected; case clang::Stmt::CXXBindTemporaryExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXBindTemporaryExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXBindTemporaryExprClass"); return ErrorUnexpected; case clang::Stmt::CXXBoolLiteralExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXBoolLiteralExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXBoolLiteralExprClass"); return ErrorUnexpected; case clang::Stmt::CXXConstructExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstructExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstructExprClass"); return ErrorUnexpected; case clang::Stmt::CXXTemporaryObjectExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTemporaryObjectExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTemporaryObjectExprClass"); return ErrorUnexpected; case clang::Stmt::CXXDefaultArgExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDefaultArgExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDefaultArgExprClass"); return ErrorUnexpected; case clang::Stmt::CXXDefaultInitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDefaultInitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDefaultInitExprClass"); return ErrorUnexpected; case clang::Stmt::CXXDeleteExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDeleteExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDeleteExprClass"); return ErrorUnexpected; case clang::Stmt::CXXDependentScopeMemberExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDependentScopeMemberExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDependentScopeMemberExprClass"); return ErrorUnexpected; case clang::Stmt::CXXFoldExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXFoldExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXFoldExprClass"); return ErrorUnexpected; case clang::Stmt::CXXInheritedCtorInitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXInheritedCtorInitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXInheritedCtorInitExprClass"); return ErrorUnexpected; case clang::Stmt::CXXNewExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNewExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNewExprClass"); return ErrorUnexpected; case clang::Stmt::CXXNoexceptExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNoexceptExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNoexceptExprClass"); return ErrorUnexpected; case clang::Stmt::CXXNullPtrLiteralExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNullPtrLiteralExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNullPtrLiteralExprClass"); return ErrorUnexpected; case clang::Stmt::CXXPseudoDestructorExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXPseudoDestructorExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXPseudoDestructorExprClass"); return ErrorUnexpected; case clang::Stmt::CXXScalarValueInitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXScalarValueInitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXScalarValueInitExprClass"); return ErrorUnexpected; case clang::Stmt::CXXStdInitializerListExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXStdInitializerListExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXStdInitializerListExprClass"); return ErrorUnexpected; case clang::Stmt::CXXThisExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXThisExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXThisExprClass"); return ErrorUnexpected; case clang::Stmt::CXXThrowExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXThrowExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXThrowExprClass"); return ErrorUnexpected; case clang::Stmt::CXXTypeidExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTypeidExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTypeidExprClass"); return ErrorUnexpected; case clang::Stmt::CXXUnresolvedConstructExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXUnresolvedConstructExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXUnresolvedConstructExprClass"); return ErrorUnexpected; case clang::Stmt::CXXUuidofExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXUuidofExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXUuidofExprClass"); return ErrorUnexpected; case clang::Stmt::CUDAKernelCallExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CUDAKernelCallExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CUDAKernelCallExprClass"); return ErrorUnexpected; case clang::Stmt::CXXMemberCallExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXMemberCallExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXMemberCallExprClass"); return ErrorUnexpected; case clang::Stmt::CXXOperatorCallExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXOperatorCallExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXOperatorCallExprClass"); return ErrorUnexpected; case clang::Stmt::UserDefinedLiteralClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C UserDefinedLiteralClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UserDefinedLiteralClass"); return ErrorUnexpected; case clang::Stmt::CXXFunctionalCastExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXFunctionalCastExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXFunctionalCastExprClass"); return ErrorUnexpected; case clang::Stmt::CXXConstCastExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstCastExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstCastExprClass"); return ErrorUnexpected; case clang::Stmt::CXXDynamicCastExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDynamicCastExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDynamicCastExprClass"); return ErrorUnexpected; case clang::Stmt::CXXReinterpretCastExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXReinterpretCastExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXReinterpretCastExprClass"); return ErrorUnexpected; case clang::Stmt::CXXStaticCastExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXStaticCastExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXStaticCastExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCBridgedCastExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBridgedCastExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBridgedCastExprClass"); return ErrorUnexpected; case clang::Stmt::CharacterLiteralClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CharacterLiteralClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CharacterLiteralClass"); return ErrorUnexpected; case clang::Stmt::ChooseExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ChooseExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ChooseExprClass"); return ErrorUnexpected; case clang::Stmt::CompoundLiteralExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CompoundLiteralExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CompoundLiteralExprClass"); return ErrorUnexpected; case clang::Stmt::ConvertVectorExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ConvertVectorExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ConvertVectorExprClass"); return ErrorUnexpected; case clang::Stmt::CoawaitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoawaitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoawaitExprClass"); return ErrorUnexpected; case clang::Stmt::CoyieldExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoyieldExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoyieldExprClass"); return ErrorUnexpected; case clang::Stmt::DependentCoawaitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C DependentCoawaitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DependentCoawaitExprClass"); return ErrorUnexpected; case clang::Stmt::DependentScopeDeclRefExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C DependentScopeDeclRefExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DependentScopeDeclRefExprClass"); return ErrorUnexpected; case clang::Stmt::DesignatedInitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C DesignatedInitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DesignatedInitExprClass"); return ErrorUnexpected; case clang::Stmt::DesignatedInitUpdateExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C DesignatedInitUpdateExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DesignatedInitUpdateExprClass"); return ErrorUnexpected; case clang::Stmt::ExpressionTraitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExpressionTraitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExpressionTraitExprClass"); return ErrorUnexpected; case clang::Stmt::ExtVectorElementExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExtVectorElementExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExtVectorElementExprClass"); return ErrorUnexpected; case clang::Stmt::FixedPointLiteralClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C FixedPointLiteralClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FixedPointLiteralClass"); return ErrorUnexpected; case clang::Stmt::FloatingLiteralClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C FloatingLiteralClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FloatingLiteralClass"); return ErrorUnexpected; case clang::Stmt::ExprWithCleanupsClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExprWithCleanupsClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExprWithCleanupsClass"); return ErrorUnexpected; case clang::Stmt::FunctionParmPackExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C FunctionParmPackExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FunctionParmPackExprClass"); return ErrorUnexpected; case clang::Stmt::GNUNullExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C GNUNullExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GNUNullExprClass"); return ErrorUnexpected; case clang::Stmt::GenericSelectionExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C GenericSelectionExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GenericSelectionExprClass"); return ErrorUnexpected; case clang::Stmt::ImaginaryLiteralClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImaginaryLiteralClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImaginaryLiteralClass"); return ErrorUnexpected; case clang::Stmt::ImplicitValueInitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImplicitValueInitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImplicitValueInitExprClass"); return ErrorUnexpected; case clang::Stmt::InitListExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C InitListExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C InitListExprClass"); return ErrorUnexpected; case clang::Stmt::LambdaExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C LambdaExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LambdaExprClass"); return ErrorUnexpected; case clang::Stmt::MSPropertyRefExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSPropertyRefExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSPropertyRefExprClass"); return ErrorUnexpected; case clang::Stmt::MSPropertySubscriptExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSPropertySubscriptExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSPropertySubscriptExprClass"); return ErrorUnexpected; case clang::Stmt::MaterializeTemporaryExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C MaterializeTemporaryExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MaterializeTemporaryExprClass"); return ErrorUnexpected; case clang::Stmt::NoInitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C NoInitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NoInitExprClass"); return ErrorUnexpected; case clang::Stmt::OMPArraySectionExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPArraySectionExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPArraySectionExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCArrayLiteralClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCArrayLiteralClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCArrayLiteralClass"); return ErrorUnexpected; case clang::Stmt::ObjCAvailabilityCheckExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAvailabilityCheckExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAvailabilityCheckExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCBoolLiteralExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBoolLiteralExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBoolLiteralExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCBoxedExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBoxedExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBoxedExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCDictionaryLiteralClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCDictionaryLiteralClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCDictionaryLiteralClass"); return ErrorUnexpected; case clang::Stmt::ObjCEncodeExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCEncodeExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCEncodeExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCIndirectCopyRestoreExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIndirectCopyRestoreExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIndirectCopyRestoreExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCIsaExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIsaExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIsaExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCIvarRefExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIvarRefExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIvarRefExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCMessageExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCMessageExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCMessageExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCPropertyRefExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCPropertyRefExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCPropertyRefExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCProtocolExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProtocolExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProtocolExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCSelectorExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCSelectorExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCSelectorExprClass"); return ErrorUnexpected; case clang::Stmt::ObjCStringLiteralClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCStringLiteralClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCStringLiteralClass"); return ErrorUnexpected; case clang::Stmt::ObjCSubscriptRefExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCSubscriptRefExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCSubscriptRefExprClass"); return ErrorUnexpected; case clang::Stmt::OffsetOfExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OffsetOfExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OffsetOfExprClass"); return ErrorUnexpected; case clang::Stmt::OpaqueValueExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OpaqueValueExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OpaqueValueExprClass"); return ErrorUnexpected; case clang::Stmt::UnresolvedLookupExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedLookupExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedLookupExprClass"); return ErrorUnexpected; case clang::Stmt::UnresolvedMemberExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedMemberExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedMemberExprClass"); return ErrorUnexpected; case clang::Stmt::PackExpansionExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C PackExpansionExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PackExpansionExprClass"); return ErrorUnexpected; case clang::Stmt::ParenListExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ParenListExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ParenListExprClass"); return ErrorUnexpected; case clang::Stmt::PseudoObjectExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C PseudoObjectExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PseudoObjectExprClass"); return ErrorUnexpected; case clang::Stmt::ShuffleVectorExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ShuffleVectorExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ShuffleVectorExprClass"); return ErrorUnexpected; case clang::Stmt::SizeOfPackExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C SizeOfPackExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SizeOfPackExprClass"); return ErrorUnexpected; case clang::Stmt::SubstNonTypeTemplateParmExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C SubstNonTypeTemplateParmExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SubstNonTypeTemplateParmExprClass"); return ErrorUnexpected; case clang::Stmt::SubstNonTypeTemplateParmPackExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C SubstNonTypeTemplateParmPackExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SubstNonTypeTemplateParmPackExprClass"); return ErrorUnexpected; case clang::Stmt::TypeTraitExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeTraitExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeTraitExprClass"); return ErrorUnexpected; case clang::Stmt::TypoExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypoExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypoExprClass"); return ErrorUnexpected; case clang::Stmt::VAArgExprClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C VAArgExprClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VAArgExprClass"); return ErrorUnexpected; case clang::Stmt::GotoStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C GotoStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GotoStmtClass"); return ErrorUnexpected; case clang::Stmt::IndirectGotoStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C IndirectGotoStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C IndirectGotoStmtClass"); return ErrorUnexpected; case clang::Stmt::LabelStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C LabelStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LabelStmtClass"); return ErrorUnexpected; case clang::Stmt::MSDependentExistsStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSDependentExistsStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSDependentExistsStmtClass"); return ErrorUnexpected; case clang::Stmt::OMPAtomicDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPAtomicDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPAtomicDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPBarrierDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPBarrierDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPBarrierDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPCancelDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCancelDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCancelDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPCancellationPointDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCancellationPointDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCancellationPointDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPCriticalDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCriticalDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCriticalDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPFlushDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPFlushDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPFlushDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPDistributeDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPDistributeParallelForDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeParallelForDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeParallelForDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPDistributeParallelForSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeParallelForSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPDistributeSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPForDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPForDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPForDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPForSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPForSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPForSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPParallelForDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelForDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelForDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPParallelForSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelForSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelForSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetParallelForSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelForSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelForSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetTeamsDistributeDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTaskLoopDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskLoopDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskLoopDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTaskLoopSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskLoopSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskLoopSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTeamsDistributeDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTeamsDistributeSimdDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeSimdDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeSimdDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPMasterDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPMasterDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPMasterDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPOrderedDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPOrderedDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPOrderedDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPParallelDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPParallelSectionsDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelSectionsDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelSectionsDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPSectionDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSectionDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSectionDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPSectionsDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSectionsDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSectionsDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPSingleDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSingleDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSingleDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetDataDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetDataDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetDataDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetEnterDataDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetEnterDataDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetEnterDataDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetExitDataDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetExitDataDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetExitDataDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetParallelDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetParallelForDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelForDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelForDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetTeamsDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTargetUpdateDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetUpdateDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetUpdateDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTaskDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTaskgroupDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskgroupDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskgroupDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTaskwaitDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskwaitDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskwaitDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTaskyieldDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskyieldDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskyieldDirectiveClass"); return ErrorUnexpected; case clang::Stmt::OMPTeamsDirectiveClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDirectiveClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDirectiveClass"); return ErrorUnexpected; case clang::Stmt::ObjCAtCatchStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtCatchStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtCatchStmtClass"); return ErrorUnexpected; case clang::Stmt::ObjCAtFinallyStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtFinallyStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtFinallyStmtClass"); return ErrorUnexpected; case clang::Stmt::ObjCAtSynchronizedStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtSynchronizedStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtSynchronizedStmtClass"); return ErrorUnexpected; case clang::Stmt::ObjCAtThrowStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtThrowStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtThrowStmtClass"); return ErrorUnexpected; case clang::Stmt::ObjCAtTryStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtTryStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtTryStmtClass"); return ErrorUnexpected; case clang::Stmt::ObjCAutoreleasePoolStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAutoreleasePoolStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAutoreleasePoolStmtClass"); return ErrorUnexpected; case clang::Stmt::ObjCForCollectionStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCForCollectionStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCForCollectionStmtClass"); return ErrorUnexpected; case clang::Stmt::SEHExceptStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHExceptStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHExceptStmtClass"); return ErrorUnexpected; case clang::Stmt::SEHFinallyStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHFinallyStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHFinallyStmtClass"); return ErrorUnexpected; case clang::Stmt::SEHLeaveStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHLeaveStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHLeaveStmtClass"); return ErrorUnexpected; case clang::Stmt::SEHTryStmtClass: - emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHTryStmtClass"); + emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHTryStmtClass"); return ErrorUnexpected; } zig_unreachable(); @@ -3855,16 +3849,16 @@ static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt * } static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) { - Buf *fn_name = buf_create_from_str(decl_name(fn_decl)); + Buf *fn_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)fn_decl)); if (get_global(c, fn_name)) { // we already saw this function return; } - AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation()); + AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), bitcast(fn_decl->getLocation())); if (proto_node == nullptr) { - emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name)); + emit_warning(c, bitcast(fn_decl->getLocation()), "unable to resolve prototype of function '%s'", buf_ptr(fn_name)); return; } @@ -3878,10 +3872,10 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) { } else if (sc == clang::SC_Extern || sc == clang::SC_Static) { proto_node->data.fn_proto.visib_mod = c->visib_mod; } else if (sc == clang::SC_PrivateExtern) { - emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern"); + emit_warning(c, bitcast(fn_decl->getLocation()), "unsupported storage class: private extern"); return; } else { - emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown"); + emit_warning(c, bitcast(fn_decl->getLocation()), "unsupported storage class: unknown"); return; } @@ -3890,7 +3884,7 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) { for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) { AstNode *param_node = proto_node->data.fn_proto.params.at(i); const clang::ParmVarDecl *param = fn_decl->getParamDecl(i); - const char *name = decl_name(param); + const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)param); Buf *proto_param_name; if (strlen(name) != 0) { @@ -3920,7 +3914,7 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) { AstNode *actual_body_node; TransScope *result_scope = trans_stmt(c, scope, body, &actual_body_node); if (result_scope == nullptr) { - emit_warning(c, fn_decl->getLocation(), "unable to translate function"); + emit_warning(c, bitcast(fn_decl->getLocation()), "unable to translate function"); return; } assert(actual_body_node != nullptr); @@ -3971,7 +3965,7 @@ static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *t } clang::QualType child_qt = typedef_decl->getUnderlyingType(); - Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); + Buf *type_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl)); if (buf_eql_str(type_name, "uint8_t")) { return resolve_typdef_as_builtin(c, typedef_decl, "u8"); @@ -4007,9 +4001,9 @@ static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *t AstNode *symbol_node = trans_create_node_symbol(c, type_name); c->decl_table.put(typedef_decl->getCanonicalDecl(), symbol_node); - AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation()); + AstNode *type_node = trans_qual_type(c, child_qt, bitcast(typedef_decl->getLocation())); if (type_node == nullptr) { - emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name)); + emit_warning(c, bitcast(typedef_decl->getLocation()), "typedef %s - unresolved child type", buf_ptr(type_name)); c->decl_table.put(typedef_decl, nullptr); // TODO add global var with type_name equal to @compileError("unable to resolve C type") return nullptr; @@ -4040,7 +4034,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) return existing_entry->value; } - const char *raw_name = decl_name(enum_decl); + const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_decl); bool is_anonymous = (raw_name[0] == 0); Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name)); @@ -4062,7 +4056,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) pure_enum = false; } } - AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation()); + AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), bitcast(enum_decl->getLocation())); assert(tag_int_type); AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); @@ -4084,7 +4078,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) { const clang::EnumConstantDecl *enum_const = *it; - Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); + Buf *enum_val_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_const)); Buf *field_name; if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) { field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); @@ -4102,7 +4096,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) // in C each enum value is in the global namespace. so we put them there too. // at this point we can rely on the enum emitting successfully if (is_anonymous) { - Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); + Buf *enum_val_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_const)); add_global_var(c, enum_val_name, int_node); } else { AstNode *field_access_node = trans_create_node_field_access(c, @@ -4123,62 +4117,63 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) } } -static AstNode *demote_struct_to_opaque(Context *c, const clang::RecordDecl *record_decl, +static AstNode *demote_struct_to_opaque(Context *c, const ZigClangRecordDecl *record_decl, Buf *full_type_name, Buf *bare_name) { AstNode *opaque_node = trans_create_node_opaque(c); if (full_type_name == nullptr) { - c->decl_table.put(record_decl->getCanonicalDecl(), opaque_node); + c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), opaque_node); return opaque_node; } AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); add_global_weak_alias(c, bare_name, full_type_name); add_global_var(c, full_type_name, opaque_node); - c->decl_table.put(record_decl->getCanonicalDecl(), symbol_node); + c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), symbol_node); return symbol_node; } -static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_decl) { - auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl()); +static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl) { + auto existing_entry = c->decl_table.maybe_get(ZigClangRecordDecl_getCanonicalDecl(record_decl)); if (existing_entry) { return existing_entry->value; } - const char *raw_name = decl_name(record_decl); + const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)record_decl); const char *container_kind_name; ContainerKind container_kind; - if (record_decl->isUnion()) { + if (ZigClangRecordDecl_isUnion(record_decl)) { container_kind_name = "union"; container_kind = ContainerKindUnion; - } else if (record_decl->isStruct()) { + } else if (ZigClangRecordDecl_isStruct(record_decl)) { container_kind_name = "struct"; container_kind = ContainerKindStruct; } else { - emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct or union", raw_name); - c->decl_table.put(record_decl->getCanonicalDecl(), nullptr); + emit_warning(c, ZigClangRecordDecl_getLocation(record_decl), + "skipping record %s, not a struct or union", raw_name); + c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), nullptr); return nullptr; } - bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0; + bool is_anonymous = ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) || raw_name[0] == 0; Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("%s_%s", container_kind_name, buf_ptr(bare_name)); - clang::RecordDecl *record_def = record_decl->getDefinition(); + const ZigClangRecordDecl *record_def = ZigClangRecordDecl_getDefinition(record_decl); if (record_def == nullptr) { return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); } // count fields and validate uint32_t field_count = 0; - for (auto it = record_def->field_begin(), - it_end = record_def->field_end(); + for (auto it = reinterpret_cast(record_def)->field_begin(), + it_end = reinterpret_cast(record_def)->field_end(); it != it_end; ++it, field_count += 1) { const clang::FieldDecl *field_decl = *it; if (field_decl->isBitField()) { - emit_warning(c, field_decl->getLocation(), "%s %s demoted to opaque type - has bitfield", + emit_warning(c, bitcast(field_decl->getLocation()), "%s %s demoted to opaque type - has bitfield", container_kind_name, is_anonymous ? "(anon)" : buf_ptr(bare_name)); return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); @@ -4195,24 +4190,25 @@ static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_ // must be before fields in case a circular reference happens if (is_anonymous) { - c->decl_table.put(record_decl->getCanonicalDecl(), struct_node); + c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), struct_node); } else { - c->decl_table.put(record_decl->getCanonicalDecl(), trans_create_node_symbol(c, full_type_name)); + c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), trans_create_node_symbol(c, full_type_name)); } uint32_t i = 0; - for (auto it = record_def->field_begin(), - it_end = record_def->field_end(); + for (auto it = reinterpret_cast(record_def)->field_begin(), + it_end = reinterpret_cast(record_def)->field_end(); it != it_end; ++it, i += 1) { const clang::FieldDecl *field_decl = *it; AstNode *field_node = trans_create_node(c, NodeTypeStructField); - field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl)); - field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation()); + field_node->data.struct_field.name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)field_decl)); + field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), + bitcast(field_decl->getLocation())); if (field_node->data.struct_field.type == nullptr) { - emit_warning(c, field_decl->getLocation(), + emit_warning(c, bitcast(field_decl->getLocation()), "%s %s demoted to opaque type - unresolved type", container_kind_name, is_anonymous ? "(anon)" : buf_ptr(bare_name)); @@ -4232,7 +4228,7 @@ static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_ } } -static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, const clang::SourceLocation &source_loc) { +static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, ZigClangSourceLocation source_loc) { switch (ap_value->getKind()) { case clang::APValue::Int: return trans_create_node_apint(c, ap_value->getInt()); @@ -4331,25 +4327,25 @@ static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::Qual } static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) { - Buf *name = buf_create_from_str(decl_name(var_decl)); + Buf *name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl)); switch (var_decl->getTLSKind()) { case clang::VarDecl::TLS_None: break; case clang::VarDecl::TLS_Static: - emit_warning(c, var_decl->getLocation(), + emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - static thread local storage", buf_ptr(name)); return; case clang::VarDecl::TLS_Dynamic: - emit_warning(c, var_decl->getLocation(), + emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name)); return; } clang::QualType qt = var_decl->getType(); - AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation()); + AstNode *var_type = trans_qual_type(c, qt, bitcast(var_decl->getLocation())); if (var_type == nullptr) { - emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name)); + emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - unresolved type", buf_ptr(name)); return; } @@ -4362,11 +4358,11 @@ static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) { if (var_decl->hasInit()) { clang::APValue *ap_value = var_decl->evaluateValue(); if (ap_value == nullptr) { - emit_warning(c, var_decl->getLocation(), + emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name)); return; } - init_node = trans_ap_value(c, ap_value, qt, var_decl->getLocation()); + init_node = trans_ap_value(c, ap_value, qt, bitcast(var_decl->getLocation())); if (init_node == nullptr) return; } else { @@ -4385,7 +4381,7 @@ static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) { return; } - emit_warning(c, var_decl->getLocation(), + emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name)); return; } @@ -4405,13 +4401,13 @@ static bool decl_visitor(void *context, const ZigClangDecl *zdecl) { resolve_enum_decl(c, static_cast(decl)); break; case clang::Decl::Record: - resolve_record_decl(c, static_cast(decl)); + resolve_record_decl(c, (const ZigClangRecordDecl *)(decl)); break; case clang::Decl::Var: visit_var_decl(c, static_cast(decl)); break; default: - emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName()); + emit_warning(c, bitcast(decl->getLocation()), "ignoring %s decl", decl->getDeclKindName()); } return true; @@ -4846,10 +4842,10 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) { clang::MacroDefinitionRecord *macro = static_cast(entity); const char *raw_name = macro->getName()->getNameStart(); clang::SourceRange range = macro->getSourceRange(); - clang::SourceLocation begin_loc = range.getBegin(); - clang::SourceLocation end_loc = range.getEnd(); + ZigClangSourceLocation begin_loc = bitcast(range.getBegin()); + ZigClangSourceLocation end_loc = bitcast(range.getEnd()); - if (begin_loc == end_loc) { + if (ZigClangSourceLocation_eq(begin_loc, end_loc)) { // this means it is a macro without a value // we don't care about such things continue; @@ -4859,7 +4855,7 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) { continue; } - const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, bitcast(begin_loc)); + const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, begin_loc); process_macro(c, &ctok, name, begin_c); } } diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 230c3c3116..7c0c787e43 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -212,3 +212,48 @@ bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *contex return reinterpret_cast(self)->visitLocalTopLevelDecls(context, reinterpret_cast(Fn)); } + +const ZigClangRecordDecl *ZigClangRecordType_getDecl(const ZigClangRecordType *record_ty) { + const clang::RecordDecl *record_decl = reinterpret_cast(record_ty)->getDecl(); + return reinterpret_cast(record_decl); +} + +const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordDecl *record_decl) { + const clang::TagDecl *tag_decl = reinterpret_cast(record_decl)->getCanonicalDecl(); + return reinterpret_cast(tag_decl); +} + +const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) { + const clang::RecordDecl *record_decl = reinterpret_cast(zig_record_decl); + const clang::RecordDecl *definition = record_decl->getDefinition(); + return reinterpret_cast(definition); +} + +bool ZigClangRecordDecl_isUnion(const ZigClangRecordDecl *record_decl) { + return reinterpret_cast(record_decl)->isUnion(); +} + +bool ZigClangRecordDecl_isStruct(const ZigClangRecordDecl *record_decl) { + return reinterpret_cast(record_decl)->isStruct(); +} + +bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *record_decl) { + return reinterpret_cast(record_decl)->isAnonymousStructOrUnion(); +} + +const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *zig_decl) { + const clang::Decl *decl = reinterpret_cast(zig_decl); + const clang::NamedDecl *named_decl = static_cast(decl); + return (const char *)named_decl->getName().bytes_begin(); +} + +ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *zig_record_decl) { + const clang::RecordDecl *record_decl = reinterpret_cast(zig_record_decl); + return bitcast(record_decl->getLocation()); +} + +bool ZigClangSourceLocation_eq(ZigClangSourceLocation zig_a, ZigClangSourceLocation zig_b) { + clang::SourceLocation a = bitcast(zig_a); + clang::SourceLocation b = bitcast(zig_b); + return a == b; +} diff --git a/src/zig_clang.h b/src/zig_clang.h index c7d749cbd9..03c20c62d6 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -16,6 +16,7 @@ // 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. struct ZigClangSourceLocation { unsigned ID; @@ -86,6 +87,7 @@ struct ZigClangStorageClass; struct ZigClangStringLiteral; struct ZigClangStringRef; struct ZigClangSwitchStmt; +struct ZigClangTagDecl; struct ZigClangType; struct ZigClangTypedefNameDecl; struct ZigClangTypedefType; @@ -256,4 +258,17 @@ 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 ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordDecl *record_decl); +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 const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *); +ZIG_EXTERN_C ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *); + +ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *decl); + +ZIG_EXTERN_C bool ZigClangSourceLocation_eq(ZigClangSourceLocation a, ZigClangSourceLocation b); #endif From 795b3e9b68986a587ac1fc9a2df6d87067d6f955 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 11 Apr 2019 09:53:47 +0200 Subject: [PATCH 030/285] Fix reading of udata/sdata encoded attributes --- std/debug.zig | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/std/debug.zig b/std/debug.zig index 2bef2e69cc..5fae39d513 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -1251,13 +1251,12 @@ const FormValue = union(enum) { }; const Constant = struct { - payload: []u8, + payload: u64, signed: bool, fn asUnsignedLe(self: *const Constant) !u64 { - if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo; if (self.signed) return error.InvalidDebugInfo; - return mem.readVarInt(u64, self.payload, builtin.Endian.Little); + return self.payload; } }; @@ -1442,11 +1441,18 @@ fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, size: usize) ! return parseFormValueBlockLen(allocator, in_stream, block_len); } -fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue { +fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, size: i32) !FormValue { return FormValue{ .Const = Constant{ .signed = signed, - .payload = try readAllocBytes(allocator, in_stream, size), + .payload = switch (size) { + 1 => try in_stream.readIntLittle(u8), + 2 => try in_stream.readIntLittle(u16), + 4 => try in_stream.readIntLittle(u32), + 8 => try in_stream.readIntLittle(u64), + -1 => if (signed) try readULeb128(in_stream) else @intCast(u64, try readILeb128(in_stream)), + else => unreachable, + }, }, }; } @@ -1484,9 +1490,8 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4), DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8), DW.FORM_udata, DW.FORM_sdata => { - const block_len = try readULeb128(in_stream); const signed = form_id == DW.FORM_sdata; - return parseFormValueConstant(allocator, in_stream, signed, block_len); + return parseFormValueConstant(allocator, in_stream, signed, -1); }, DW.FORM_exprloc => { const size = try readULeb128(in_stream); From 29ec409b52827ae815564deaecb8f7529bb47444 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 11 Apr 2019 09:55:02 +0200 Subject: [PATCH 031/285] Add definition for DW_AT_alignment Even though it's been standardized in DWARF5 some compilers produce it anyway for DWARF4 infos too. --- std/dwarf.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/std/dwarf.zig b/std/dwarf.zig index 2cf8ed953e..af73ada9e5 100644 --- a/std/dwarf.zig +++ b/std/dwarf.zig @@ -241,6 +241,9 @@ pub const AT_const_expr = 0x6c; pub const AT_enum_class = 0x6d; pub const AT_linkage_name = 0x6e; +// DWARF 5 +pub const AT_alignment = 0x88; + pub const AT_lo_user = 0x2000; // Implementation-defined range start. pub const AT_hi_user = 0x3fff; // Implementation-defined range end. From 38492b2ea4b7aac9685ede264701ac0b7bb291c0 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 11 Apr 2019 10:35:35 +0200 Subject: [PATCH 032/285] Fix reading of reference attributes --- std/debug.zig | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/std/debug.zig b/std/debug.zig index 5fae39d513..f29c2869af 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -1243,9 +1243,7 @@ const FormValue = union(enum) { ExprLoc: []u8, Flag: bool, SecOffset: u64, - Ref: []u8, RefAddr: u64, - RefSig8: u64, String: []u8, StrPtr: u64, }; @@ -1465,14 +1463,17 @@ fn parseFormValueTargetAddrSize(in_stream: var) !u64 { return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLittle(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLittle(u64) else unreachable; } -fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue { - const buf = try readAllocBytes(allocator, in_stream, size); - return FormValue{ .Ref = buf }; -} - -fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, comptime T: type) !FormValue { - const block_len = try in_stream.readIntLittle(T); - return parseFormValueRefLen(allocator, in_stream, block_len); +fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, size: i32) !FormValue { + return FormValue{ + .RefAddr = switch (size) { + 1 => try in_stream.readIntLittle(u8), + 2 => try in_stream.readIntLittle(u16), + 4 => try in_stream.readIntLittle(u32), + 8 => try in_stream.readIntLittle(u64), + -1 => try readULeb128(in_stream), + else => unreachable, + }, + }; } fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64: bool) anyerror!FormValue { @@ -1502,17 +1503,14 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 DW.FORM_flag_present => FormValue{ .Flag = true }, DW.FORM_sec_offset => FormValue{ .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, - DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8), - DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16), - DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, u32), - DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64), - DW.FORM_ref_udata => { - const ref_len = try readULeb128(in_stream); - return parseFormValueRefLen(allocator, in_stream, ref_len); - }, + DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, 1), + DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, 2), + DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, 4), + DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, 8), + DW.FORM_ref_udata => parseFormValueRef(allocator, in_stream, -1), DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, - DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLittle(u64) }, + DW.FORM_ref_sig8 => FormValue{ .RefAddr = try in_stream.readIntLittle(u64) }, DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) }, DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, From 51eb4ebec1435dc0050bd1d40c48416019972e65 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 11 Apr 2019 15:41:42 +0200 Subject: [PATCH 033/285] Distinguish between absolute/relative addresses --- std/debug.zig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/std/debug.zig b/std/debug.zig index f29c2869af..ec3f609022 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -1243,6 +1243,7 @@ const FormValue = union(enum) { ExprLoc: []u8, Flag: bool, SecOffset: u64, + Ref: u64, RefAddr: u64, String: []u8, StrPtr: u64, @@ -1465,7 +1466,7 @@ fn parseFormValueTargetAddrSize(in_stream: var) !u64 { fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, size: i32) !FormValue { return FormValue{ - .RefAddr = switch (size) { + .Ref = switch (size) { 1 => try in_stream.readIntLittle(u8), 2 => try in_stream.readIntLittle(u16), 4 => try in_stream.readIntLittle(u32), @@ -1510,7 +1511,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 DW.FORM_ref_udata => parseFormValueRef(allocator, in_stream, -1), DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, - DW.FORM_ref_sig8 => FormValue{ .RefAddr = try in_stream.readIntLittle(u64) }, + DW.FORM_ref_sig8 => FormValue{ .Ref = try in_stream.readIntLittle(u64) }, DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) }, DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) }, From 27cd830ec8ca1ddba692c65e8a129a2b5c9a1673 Mon Sep 17 00:00:00 2001 From: Matthew Iannucci Date: Thu, 11 Apr 2019 13:15:17 -0400 Subject: [PATCH 034/285] Add initial support for iOS targets (#2237) * Add iOS C int sizes... try to hack in iOS DebugInfo * Get rid of ios link check for now * Remove macos linkversion check --- src/link.cpp | 10 ---------- src/target.cpp | 17 ++++++++++++++++- std/debug.zig | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/link.cpp b/src/link.cpp index 70f91f2b8e..2a152e1d1e 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1562,16 +1562,6 @@ static void construct_linker_job_macho(LinkJob *lj) { lj->args.append("dynamic_lookup"); } - if (platform.kind == MacOS) { - if (darwin_version_lt(&platform, 10, 5)) { - lj->args.append("-lgcc_s.10.4"); - } else if (darwin_version_lt(&platform, 10, 6)) { - lj->args.append("-lgcc_s.10.5"); - } - } else { - zig_panic("TODO"); - } - for (size_t i = 0; i < g->darwin_frameworks.length; i += 1) { lj->args.append("-framework"); lj->args.append(buf_ptr(g->darwin_frameworks.at(i))); diff --git a/src/target.cpp b/src/target.cpp index dda8188765..3b4265359c 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -894,10 +894,25 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) { case CIntTypeCount: zig_unreachable(); } + case OsIOS: + switch (id) { + case CIntTypeShort: + case CIntTypeUShort: + return 16; + case CIntTypeInt: + case CIntTypeUInt: + return 32; + case CIntTypeLong: + case CIntTypeULong: + case CIntTypeLongLong: + case CIntTypeULongLong: + return 64; + case CIntTypeCount: + zig_unreachable(); + } case OsAnanas: case OsCloudABI: case OsDragonFly: - case OsIOS: case OsKFreeBSD: case OsLv2: case OsSolaris: diff --git a/std/debug.zig b/std/debug.zig index c85a982059..bfcfbc6e77 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -1178,7 +1178,7 @@ pub const DwarfInfo = struct { }; pub const DebugInfo = switch (builtin.os) { - builtin.Os.macosx => struct { + builtin.Os.macosx, builtin.Os.ios => struct { symbols: []const MachoSymbol, strings: []const u8, ofiles: OFileTable, From a895c59971d16481a85b6bff7618a3f9e2a4e0ae Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 11 Apr 2019 14:33:43 -0400 Subject: [PATCH 035/285] delete unused function missed by 27cd830ec8ca1dd --- src/link.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/link.cpp b/src/link.cpp index 2a152e1d1e..78e549c80b 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1426,18 +1426,6 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { } } -static bool darwin_version_lt(DarwinPlatform *platform, int major, int minor) { - if (platform->major < major) { - return true; - } else if (platform->major > major) { - return false; - } - if (platform->minor < minor) { - return true; - } - return false; -} - static void construct_linker_job_macho(LinkJob *lj) { CodeGen *g = lj->codegen; From 4172fe986e51a665605bcd07b0ed5998796c0c52 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 11 Apr 2019 15:22:15 -0400 Subject: [PATCH 036/285] readme: separate powerpc 32 and 64 bit in the support table --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a860e4e5d..4e14e81c34 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,8 @@ Zig is an open-source programming language designed for **robustness**, |bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | |hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | |mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | -|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|powerpc32 | Tier 3 | Tier 3 | Tier 4 | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | +|powerpc64 | Tier 3 | Tier 3 | Tier 4 | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | |amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | |sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | |s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 | From b960f1d92275057e8db1fc2cfee77abebf9e4c3e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 11 Apr 2019 15:33:05 -0400 Subject: [PATCH 037/285] translate-c: move some code to the C API See #1964 --- src/translate_c.cpp | 46 +++++++++++++++++++++++---------------------- src/zig_clang.cpp | 25 ++++++++++++++++++++++++ src/zig_clang.h | 13 +++++++++++-- 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 5307e3030d..0e4d21475b 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -113,7 +113,7 @@ static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *paren static TransScopeBlock *trans_scope_block_find(TransScope *scope); static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl); -static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl); +static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl); static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl); static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *stmt, @@ -1128,8 +1128,8 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca } case clang::Type::Enum: { - const clang::EnumType *enum_ty = static_cast(ty); - return resolve_enum_decl(c, enum_ty->getDecl()); + const ZigClangEnumType *enum_ty = reinterpret_cast(ty); + return resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty)); } case clang::Type::ConstantArray: { @@ -2673,8 +2673,8 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope * case clang::Type::Enum: { - const clang::EnumType *enum_ty = static_cast(ty); - AstNode *enum_type = resolve_enum_decl(c, enum_ty->getDecl()); + const ZigClangEnumType *enum_ty = reinterpret_cast(ty); + AstNode *enum_type = resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty)); return to_enum_zero_cmp(c, res, enum_type); } @@ -4013,23 +4013,23 @@ static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *t return symbol_node; } -struct AstNode *demote_enum_to_opaque(Context *c, const clang::EnumDecl *enum_decl, - Buf *full_type_name, Buf *bare_name) +struct AstNode *demote_enum_to_opaque(Context *c, const ZigClangEnumDecl *enum_decl, Buf *full_type_name, + Buf *bare_name) { AstNode *opaque_node = trans_create_node_opaque(c); if (full_type_name == nullptr) { - c->decl_table.put(enum_decl->getCanonicalDecl(), opaque_node); + c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), opaque_node); return opaque_node; } AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); add_global_weak_alias(c, bare_name, full_type_name); add_global_var(c, full_type_name, opaque_node); - c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); + c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), symbol_node); return symbol_node; } -static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) { - auto existing_entry = c->decl_table.maybe_get((void*)enum_decl->getCanonicalDecl()); +static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl) { + auto existing_entry = c->decl_table.maybe_get(ZigClangEnumDecl_getCanonicalDecl(enum_decl)); if (existing_entry) { return existing_entry->value; } @@ -4039,7 +4039,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name)); - const clang::EnumDecl *enum_def = enum_decl->getDefinition(); + const ZigClangEnumDecl *enum_def = ZigClangEnumDecl_getDefinition(enum_decl); if (!enum_def) { return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name); } @@ -4047,8 +4047,8 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) bool pure_enum = true; uint32_t field_count = 0; - for (auto it = enum_def->enumerator_begin(), - it_end = enum_def->enumerator_end(); + for (auto it = reinterpret_cast(enum_def)->enumerator_begin(), + it_end = reinterpret_cast(enum_def)->enumerator_end(); it != it_end; ++it, field_count += 1) { const clang::EnumConstantDecl *enum_const = *it; @@ -4056,7 +4056,9 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) pure_enum = false; } } - AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), bitcast(enum_decl->getLocation())); + AstNode *tag_int_type = trans_qual_type(c, + bitcast(ZigClangEnumDecl_getIntegerType(enum_decl)), + ZigClangEnumDecl_getLocation(enum_decl)); assert(tag_int_type); AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); @@ -4065,15 +4067,15 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) // TODO only emit this tag type if the enum tag type is not the default. // I don't know what the default is, need to figure out how clang is deciding. // it appears to at least be different across gcc/msvc - if (!c_is_builtin_type(c, enum_decl->getIntegerType(), clang::BuiltinType::UInt) && - !c_is_builtin_type(c, enum_decl->getIntegerType(), clang::BuiltinType::Int)) + if (!c_is_builtin_type(c, bitcast(ZigClangEnumDecl_getIntegerType(enum_decl)), clang::BuiltinType::UInt) && + !c_is_builtin_type(c, bitcast(ZigClangEnumDecl_getIntegerType(enum_decl)), clang::BuiltinType::Int)) { enum_node->data.container_decl.init_arg_expr = tag_int_type; } enum_node->data.container_decl.fields.resize(field_count); uint32_t i = 0; - for (auto it = enum_def->enumerator_begin(), - it_end = enum_def->enumerator_end(); + for (auto it = reinterpret_cast(enum_def)->enumerator_begin(), + it_end = reinterpret_cast(enum_def)->enumerator_end(); it != it_end; ++it, i += 1) { const clang::EnumConstantDecl *enum_const = *it; @@ -4106,13 +4108,13 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) } if (is_anonymous) { - c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node); + c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), enum_node); return enum_node; } else { AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); add_global_weak_alias(c, bare_name, full_type_name); add_global_var(c, full_type_name, enum_node); - c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); + c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), symbol_node); return enum_node; } } @@ -4398,7 +4400,7 @@ static bool decl_visitor(void *context, const ZigClangDecl *zdecl) { resolve_typedef_decl(c, static_cast(decl)); break; case clang::Decl::Enum: - resolve_enum_decl(c, static_cast(decl)); + resolve_enum_decl(c, reinterpret_cast(decl)); break; case clang::Decl::Record: resolve_record_decl(c, (const ZigClangRecordDecl *)(decl)); diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 7c0c787e43..7493208450 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -218,17 +218,33 @@ const ZigClangRecordDecl *ZigClangRecordType_getDecl(const ZigClangRecordType *r return reinterpret_cast(record_decl); } +const ZigClangEnumDecl *ZigClangEnumType_getDecl(const ZigClangEnumType *enum_ty) { + const clang::EnumDecl *enum_decl = reinterpret_cast(enum_ty)->getDecl(); + return reinterpret_cast(enum_decl); +} + const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordDecl *record_decl) { const clang::TagDecl *tag_decl = reinterpret_cast(record_decl)->getCanonicalDecl(); return reinterpret_cast(tag_decl); } +const ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const ZigClangEnumDecl *enum_decl) { + const clang::TagDecl *tag_decl = reinterpret_cast(enum_decl)->getCanonicalDecl(); + return reinterpret_cast(tag_decl); +} + const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) { const clang::RecordDecl *record_decl = reinterpret_cast(zig_record_decl); const clang::RecordDecl *definition = record_decl->getDefinition(); return reinterpret_cast(definition); } +const ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const ZigClangEnumDecl *zig_enum_decl) { + const clang::EnumDecl *enum_decl = reinterpret_cast(zig_enum_decl); + const clang::EnumDecl *definition = enum_decl->getDefinition(); + return reinterpret_cast(definition); +} + bool ZigClangRecordDecl_isUnion(const ZigClangRecordDecl *record_decl) { return reinterpret_cast(record_decl)->isUnion(); } @@ -252,8 +268,17 @@ ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl * return bitcast(record_decl->getLocation()); } +ZigClangSourceLocation ZigClangEnumDecl_getLocation(const ZigClangEnumDecl *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getLocation()); +} + bool ZigClangSourceLocation_eq(ZigClangSourceLocation zig_a, ZigClangSourceLocation zig_b) { clang::SourceLocation a = bitcast(zig_a); clang::SourceLocation b = bitcast(zig_b); return a == b; } + +ZigClangQualType ZigClangEnumDecl_getIntegerType(const ZigClangEnumDecl *self) { + return bitcast(reinterpret_cast(self)->getIntegerType()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 03c20c62d6..c15fe84d97 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -260,13 +260,22 @@ ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *, voi 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 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 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 const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *); -ZIG_EXTERN_C ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *); + +ZIG_EXTERN_C ZigClangQualType ZigClangEnumDecl_getIntegerType(const ZigClangEnumDecl *); ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *decl); From 5f8dbcac0669973b0d0f07ce6777dcd4456676dd Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Thu, 11 Apr 2019 15:29:13 -0500 Subject: [PATCH 038/285] wasm: disable error ret tracing --- src/codegen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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; From 6f34d08aedb4c89257de04da1e4f8d162188d247 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 11 Apr 2019 23:38:41 -0400 Subject: [PATCH 039/285] translate-c: move some code to the C API See #1964 --- src/translate_c.cpp | 47 ++++++++++++++++++++++++--------------------- src/zig_clang.cpp | 22 +++++++++++++++++++++ src/zig_clang.h | 5 +++++ 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 0e4d21475b..cfa0e7efef 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -114,7 +114,7 @@ static TransScopeBlock *trans_scope_block_find(TransScope *scope); static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl); static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl); -static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl); +static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl); static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *stmt, ResultUsed result_used, TransLRValue lrval, @@ -592,7 +592,7 @@ static bool qual_type_is_fn_ptr(clang::QualType qt) { return false; } -static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, ZigClangSourceLocation source_loc) { +static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType qt, ZigClangSourceLocation source_loc) { const clang::Type *ty = qt.getTypePtr(); switch (ty->getTypeClass()) { case clang::Type::Builtin: @@ -614,8 +614,8 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, Z } case clang::Type::Typedef: { - const clang::TypedefType *typedef_ty = static_cast(ty); - const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); + const ZigClangTypedefType *typedef_ty = reinterpret_cast(ty); + const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); const char *type_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl); if (strcmp(type_name, "uint8_t") == 0 || strcmp(type_name, "int8_t") == 0) { return 8; @@ -636,7 +636,7 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, Z } -static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType &qt, +static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType qt, ZigClangSourceLocation source_loc) { uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc); @@ -669,7 +669,7 @@ static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType &qt, return log2int_fn_call; } -static bool qual_type_child_is_fn_proto(const clang::QualType &qt) { +static bool qual_type_child_is_fn_proto(const clang::QualType qt) { if (qt.getTypePtr()->getTypeClass() == clang::Type::Paren) { const clang::ParenType *paren_type = static_cast(qt.getTypePtr()); if (paren_type->getInnerType()->getTypeClass() == clang::Type::FunctionProto) { @@ -797,9 +797,11 @@ static bool type_is_opaque(Context *c, const clang::Type *ty, ZigClangSourceLoca return type_is_opaque(c, elaborated_ty->getNamedType().getTypePtr(), source_loc); } case clang::Type::Typedef: { - const clang::TypedefType *typedef_ty = static_cast(ty); - const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); - return type_is_opaque(c, typedef_decl->getUnderlyingType().getTypePtr(), source_loc); + const ZigClangTypedefType *typedef_ty = reinterpret_cast(ty); + const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); + ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); + clang::QualType qt = bitcast(underlying_type); + return type_is_opaque(c, qt.getTypePtr(), source_loc); } default: return false; @@ -978,8 +980,8 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca } case clang::Type::Typedef: { - const clang::TypedefType *typedef_ty = static_cast(ty); - const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); + const ZigClangTypedefType *typedef_ty = reinterpret_cast(ty); + const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); return resolve_typedef_decl(c, typedef_decl); } case clang::Type::Elaborated: @@ -2661,9 +2663,9 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope * case clang::Type::Typedef: { - const clang::TypedefType *typedef_ty = static_cast(ty); - const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); - auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl->getCanonicalDecl()); + const ZigClangTypedefType *typedef_ty = reinterpret_cast(ty); + const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); + auto existing_entry = c->decl_table.maybe_get((void*)ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)); if (existing_entry) { return existing_entry->value; } @@ -3952,19 +3954,19 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) { add_top_level_decl(c, fn_def_node->data.fn_def.fn_proto->data.fn_proto.name, fn_def_node); } -static AstNode *resolve_typdef_as_builtin(Context *c, const clang::TypedefNameDecl *typedef_decl, const char *primitive_name) { +static AstNode *resolve_typdef_as_builtin(Context *c, const ZigClangTypedefNameDecl *typedef_decl, const char *primitive_name) { AstNode *node = trans_create_node_symbol_str(c, primitive_name); c->decl_table.put(typedef_decl, node); return node; } -static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl) { - auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl->getCanonicalDecl()); +static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl) { + auto existing_entry = c->decl_table.maybe_get((void*)ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)); if (existing_entry) { return existing_entry->value; } - clang::QualType child_qt = typedef_decl->getUnderlyingType(); + ZigClangQualType child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); Buf *type_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl)); if (buf_eql_str(type_name, "uint8_t")) { @@ -3999,11 +4001,12 @@ static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *t // trans_qual_type here might cause us to look at this typedef again so we put the item in the map first AstNode *symbol_node = trans_create_node_symbol(c, type_name); - c->decl_table.put(typedef_decl->getCanonicalDecl(), symbol_node); + c->decl_table.put(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl), symbol_node); - AstNode *type_node = trans_qual_type(c, child_qt, bitcast(typedef_decl->getLocation())); + AstNode *type_node = trans_qual_type(c, bitcast(child_qt), ZigClangTypedefNameDecl_getLocation(typedef_decl)); if (type_node == nullptr) { - emit_warning(c, bitcast(typedef_decl->getLocation()), "typedef %s - unresolved child type", buf_ptr(type_name)); + emit_warning(c, ZigClangTypedefNameDecl_getLocation(typedef_decl), + "typedef %s - unresolved child type", buf_ptr(type_name)); c->decl_table.put(typedef_decl, nullptr); // TODO add global var with type_name equal to @compileError("unable to resolve C type") return nullptr; @@ -4397,7 +4400,7 @@ static bool decl_visitor(void *context, const ZigClangDecl *zdecl) { visit_fn_decl(c, static_cast(decl)); break; case clang::Decl::Typedef: - resolve_typedef_decl(c, static_cast(decl)); + resolve_typedef_decl(c, reinterpret_cast(decl)); break; case clang::Decl::Enum: resolve_enum_decl(c, reinterpret_cast(decl)); diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 7493208450..4f50c5d3d3 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -233,6 +233,11 @@ const ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const ZigClangEnumDecl return reinterpret_cast(tag_decl); } +const ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const ZigClangTypedefNameDecl *self) { + const clang::TypedefNameDecl *decl = reinterpret_cast(self)->getCanonicalDecl(); + return reinterpret_cast(decl); +} + const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) { const clang::RecordDecl *record_decl = reinterpret_cast(zig_record_decl); const clang::RecordDecl *definition = record_decl->getDefinition(); @@ -273,6 +278,11 @@ ZigClangSourceLocation ZigClangEnumDecl_getLocation(const ZigClangEnumDecl *self return bitcast(casted->getLocation()); } +ZigClangSourceLocation ZigClangTypedefNameDecl_getLocation(const ZigClangTypedefNameDecl *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getLocation()); +} + bool ZigClangSourceLocation_eq(ZigClangSourceLocation zig_a, ZigClangSourceLocation zig_b) { clang::SourceLocation a = bitcast(zig_a); clang::SourceLocation b = bitcast(zig_b); @@ -282,3 +292,15 @@ bool ZigClangSourceLocation_eq(ZigClangSourceLocation zig_a, ZigClangSourceLocat ZigClangQualType ZigClangEnumDecl_getIntegerType(const ZigClangEnumDecl *self) { return bitcast(reinterpret_cast(self)->getIntegerType()); } + +const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) { + auto casted = reinterpret_cast(self); + const clang::TypedefNameDecl *name_decl = casted->getDecl(); + return reinterpret_cast(name_decl); +} + +ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(const ZigClangTypedefNameDecl *self) { + auto casted = reinterpret_cast(self); + clang::QualType ty = casted->getUnderlyingType(); + return bitcast(ty); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index c15fe84d97..c534addf9e 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -264,12 +264,14 @@ ZIG_EXTERN_C const ZigClangEnumDecl *ZigClangEnumType_getDecl(const ZigClangEnum 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); @@ -280,4 +282,7 @@ ZIG_EXTERN_C ZigClangQualType ZigClangEnumDecl_getIntegerType(const ZigClangEnum 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 *); #endif From f860493f23f0c438e76268b412f85e7b9843ea89 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 12 Apr 2019 03:12:22 -0400 Subject: [PATCH 040/285] translate-c: move some code to the C API See #1964 --- src/translate_c.cpp | 537 ++++++++++++++++++++++---------------------- src/zig_clang.cpp | 262 +++++++++++++++++---- src/zig_clang.h | 62 +++++ 3 files changed, 544 insertions(+), 317 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index cfa0e7efef..84770844b7 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -122,9 +122,9 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st TransScope **out_node_scope); static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node); static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval); -static AstNode *trans_qual_type(Context *c, clang::QualType qt, ZigClangSourceLocation source_loc); +static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc); static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval); -static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, ZigClangSourceLocation source_loc); +static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, ZigClangQualType qt, ZigClangSourceLocation source_loc); static ZigClangSourceLocation bitcast(clang::SourceLocation src) { ZigClangSourceLocation dest; @@ -136,11 +136,11 @@ static ZigClangQualType bitcast(clang::QualType src) { memcpy(&dest, static_cast(&src), sizeof(ZigClangQualType)); return dest; } -static clang::QualType bitcast(ZigClangQualType src) { - clang::QualType dest; - memcpy(&dest, static_cast(&src), sizeof(ZigClangQualType)); - return dest; -} +//static clang::QualType bitcast(ZigClangQualType src) { +// clang::QualType dest; +// memcpy(&dest, static_cast(&src), sizeof(ZigClangQualType)); +// return dest; +//} ATTRIBUTE_PRINTF(3, 4) static void emit_warning(Context *c, ZigClangSourceLocation sl, const char *format, ...) { @@ -502,88 +502,77 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) } -static const clang::Type *qual_type_canon(clang::QualType qt) { - return qt.getCanonicalType().getTypePtr(); +static const ZigClangType *qual_type_canon(ZigClangQualType qt) { + ZigClangQualType canon = ZigClangQualType_getCanonicalType(qt); + return ZigClangQualType_getTypePtr(canon); } -static clang::QualType get_expr_qual_type(Context *c, const clang::Expr *expr) { +static ZigClangQualType get_expr_qual_type(Context *c, const clang::Expr *expr) { // String literals in C are `char *` but they should really be `const char *`. if (expr->getStmtClass() == clang::Stmt::ImplicitCastExprClass) { const clang::ImplicitCastExpr *cast_expr = static_cast(expr); if (cast_expr->getCastKind() == clang::CK_ArrayToPointerDecay) { const clang::Expr *sub_expr = cast_expr->getSubExpr(); if (sub_expr->getStmtClass() == clang::Stmt::StringLiteralClass) { - clang::QualType array_qt = sub_expr->getType(); - const clang::ArrayType *array_type = static_cast(array_qt.getTypePtr()); - clang::QualType pointee_qt = array_type->getElementType(); - pointee_qt.addConst(); - return bitcast(ZigClangASTContext_getPointerType(c->ctx, bitcast(pointee_qt))); + ZigClangQualType array_qt = bitcast(sub_expr->getType()); + const clang::ArrayType *array_type = reinterpret_cast( + ZigClangQualType_getTypePtr(array_qt)); + ZigClangQualType pointee_qt = bitcast(array_type->getElementType()); + ZigClangQualType_addConst(&pointee_qt); + return ZigClangASTContext_getPointerType(c->ctx, pointee_qt); } } } - return expr->getType(); + return bitcast(expr->getType()); } -static clang::QualType get_expr_qual_type_before_implicit_cast(Context *c, const clang::Expr *expr) { +static ZigClangQualType get_expr_qual_type_before_implicit_cast(Context *c, const clang::Expr *expr) { if (expr->getStmtClass() == clang::Stmt::ImplicitCastExprClass) { const clang::ImplicitCastExpr *cast_expr = static_cast(expr); return get_expr_qual_type(c, cast_expr->getSubExpr()); } - return expr->getType(); + return bitcast(expr->getType()); } static AstNode *get_expr_type(Context *c, const clang::Expr *expr) { return trans_qual_type(c, get_expr_qual_type(c, expr), bitcast(expr->getBeginLoc())); } -static bool qual_types_equal(clang::QualType t1, clang::QualType t2) { - if (t1.isConstQualified() != t2.isConstQualified()) { - return false; - } - if (t1.isVolatileQualified() != t2.isVolatileQualified()) { - return false; - } - if (t1.isRestrictQualified() != t2.isRestrictQualified()) { - return false; - } - return t1.getTypePtr() == t2.getTypePtr(); -} - static bool is_c_void_type(AstNode *node) { return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void")); } static bool expr_types_equal(Context *c, const clang::Expr *expr1, const clang::Expr *expr2) { - clang::QualType t1 = get_expr_qual_type(c, expr1); - clang::QualType t2 = get_expr_qual_type(c, expr2); + ZigClangQualType t1 = get_expr_qual_type(c, expr1); + ZigClangQualType t2 = get_expr_qual_type(c, expr2); - return qual_types_equal(t1, t2); + return ZigClangQualType_eq(t1, t2); } -static bool qual_type_is_ptr(clang::QualType qt) { - const clang::Type *ty = qual_type_canon(qt); - return ty->getTypeClass() == clang::Type::Pointer; +static bool qual_type_is_ptr(ZigClangQualType qt) { + const ZigClangType *ty = qual_type_canon(qt); + return ZigClangType_getTypeClass(ty) == ZigClangType_Pointer; } -static const clang::FunctionProtoType *qual_type_get_fn_proto(clang::QualType qt, bool *is_ptr) { - const clang::Type *ty = qual_type_canon(qt); +static const clang::FunctionProtoType *qual_type_get_fn_proto(ZigClangQualType qt, bool *is_ptr) { + const ZigClangType *ty = qual_type_canon(qt); *is_ptr = false; - if (ty->getTypeClass() == clang::Type::Pointer) { + if (ZigClangType_getTypeClass(ty) == ZigClangType_Pointer) { *is_ptr = true; - const clang::PointerType *pointer_ty = static_cast(ty); - clang::QualType child_qt = pointer_ty->getPointeeType(); - ty = child_qt.getTypePtr(); + const clang::PointerType *pointer_ty = reinterpret_cast(ty); + ZigClangQualType child_qt = bitcast(pointer_ty->getPointeeType()); + ty = ZigClangQualType_getTypePtr(child_qt); } - if (ty->getTypeClass() == clang::Type::FunctionProto) { - return static_cast(ty); + if (ZigClangType_getTypeClass(ty) == ZigClangType_FunctionProto) { + return reinterpret_cast(ty); } return nullptr; } -static bool qual_type_is_fn_ptr(clang::QualType qt) { +static bool qual_type_is_fn_ptr(ZigClangQualType qt) { bool is_ptr; if (qual_type_get_fn_proto(qt, &is_ptr)) { return is_ptr; @@ -592,12 +581,12 @@ static bool qual_type_is_fn_ptr(clang::QualType qt) { return false; } -static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType qt, ZigClangSourceLocation source_loc) { - const clang::Type *ty = qt.getTypePtr(); - switch (ty->getTypeClass()) { - case clang::Type::Builtin: +static uint32_t qual_type_int_bit_width(Context *c, const ZigClangQualType qt, ZigClangSourceLocation source_loc) { + const ZigClangType *ty = ZigClangQualType_getTypePtr(qt); + switch (ZigClangType_getTypeClass(ty)) { + case ZigClangType_Builtin: { - const clang::BuiltinType *builtin_ty = static_cast(ty); + const clang::BuiltinType *builtin_ty = reinterpret_cast(ty); switch (builtin_ty->getKind()) { case clang::BuiltinType::Char_U: case clang::BuiltinType::UChar: @@ -612,7 +601,7 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType qt, Zi } zig_unreachable(); } - case clang::Type::Typedef: + case ZigClangType_Typedef: { const ZigClangTypedefType *typedef_ty = reinterpret_cast(ty); const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); @@ -636,7 +625,7 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType qt, Zi } -static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType qt, +static AstNode *qual_type_to_log2_int_ref(Context *c, const ZigClangQualType qt, ZigClangSourceLocation source_loc) { uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc); @@ -669,30 +658,31 @@ static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType qt, return log2int_fn_call; } -static bool qual_type_child_is_fn_proto(const clang::QualType qt) { - if (qt.getTypePtr()->getTypeClass() == clang::Type::Paren) { - const clang::ParenType *paren_type = static_cast(qt.getTypePtr()); +static bool qual_type_child_is_fn_proto(ZigClangQualType qt) { + const ZigClangType *ty = ZigClangQualType_getTypePtr(qt); + if (ZigClangType_getTypeClass(ty) == ZigClangType_Paren) { + const clang::ParenType *paren_type = reinterpret_cast(ty); if (paren_type->getInnerType()->getTypeClass() == clang::Type::FunctionProto) { return true; } - } else if (qt.getTypePtr()->getTypeClass() == clang::Type::Attributed) { - const clang::AttributedType *attr_type = static_cast(qt.getTypePtr()); - return qual_type_child_is_fn_proto(attr_type->getEquivalentType()); + } else if (ZigClangType_getTypeClass(ty) == ZigClangType_Attributed) { + const clang::AttributedType *attr_type = reinterpret_cast(ty); + return qual_type_child_is_fn_proto(bitcast(attr_type->getEquivalentType())); } return false; } -static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, clang::QualType dest_type, - clang::QualType src_type, AstNode *expr) +static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type, + ZigClangQualType src_type, AstNode *expr) { // The only way void pointer casts are valid C code, is if // the value of the expression is ignored. We therefore just // return the expr, and let the system that ignores values // translate this correctly. - if (qual_type_canon(dest_type)->isVoidType()) { + if (ZigClangType_isVoidType(qual_type_canon(dest_type))) { return expr; } - if (qual_types_equal(dest_type, src_type)) { + if (ZigClangQualType_eq(dest_type, src_type)) { return expr; } if (qual_type_is_ptr(dest_type) && qual_type_is_ptr(src_type)) { @@ -707,11 +697,11 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr); } -static bool c_is_signed_integer(Context *c, clang::QualType qt) { - const clang::Type *c_type = qual_type_canon(qt); - if (c_type->getTypeClass() != clang::Type::Builtin) +static bool c_is_signed_integer(Context *c, ZigClangQualType qt) { + const ZigClangType *c_type = qual_type_canon(qt); + if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin) return false; - const clang::BuiltinType *builtin_ty = static_cast(c_type); + const clang::BuiltinType *builtin_ty = reinterpret_cast(c_type); switch (builtin_ty->getKind()) { case clang::BuiltinType::SChar: case clang::BuiltinType::Short: @@ -726,11 +716,11 @@ static bool c_is_signed_integer(Context *c, clang::QualType qt) { } } -static bool c_is_unsigned_integer(Context *c, clang::QualType qt) { - const clang::Type *c_type = qual_type_canon(qt); - if (c_type->getTypeClass() != clang::Type::Builtin) +static bool c_is_unsigned_integer(Context *c, ZigClangQualType qt) { + const ZigClangType *c_type = qual_type_canon(qt); + if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin) return false; - const clang::BuiltinType *builtin_ty = static_cast(c_type); + const clang::BuiltinType *builtin_ty = reinterpret_cast(c_type); switch (builtin_ty->getKind()) { case clang::BuiltinType::Char_U: case clang::BuiltinType::UChar: @@ -747,19 +737,19 @@ static bool c_is_unsigned_integer(Context *c, clang::QualType qt) { } } -static bool c_is_builtin_type(Context *c, clang::QualType qt, clang::BuiltinType::Kind kind) { - const clang::Type *c_type = qual_type_canon(qt); - if (c_type->getTypeClass() != clang::Type::Builtin) +static bool c_is_builtin_type(Context *c, ZigClangQualType qt, clang::BuiltinType::Kind kind) { + const ZigClangType *c_type = qual_type_canon(qt); + if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin) return false; - const clang::BuiltinType *builtin_ty = static_cast(c_type); + const clang::BuiltinType *builtin_ty = reinterpret_cast(c_type); return builtin_ty->getKind() == kind; } -static bool c_is_float(Context *c, clang::QualType qt) { - const clang::Type *c_type = qt.getTypePtr(); - if (c_type->getTypeClass() != clang::Type::Builtin) +static bool c_is_float(Context *c, ZigClangQualType qt) { + const ZigClangType *c_type = ZigClangQualType_getTypePtr(qt); + if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin) return false; - const clang::BuiltinType *builtin_ty = static_cast(c_type); + const clang::BuiltinType *builtin_ty = reinterpret_cast(c_type); switch (builtin_ty->getKind()) { case clang::BuiltinType::Half: case clang::BuiltinType::Float: @@ -772,7 +762,7 @@ static bool c_is_float(Context *c, clang::QualType qt) { } } -static bool qual_type_has_wrapping_overflow(Context *c, clang::QualType qt) { +static bool qual_type_has_wrapping_overflow(Context *c, ZigClangQualType qt) { if (c_is_signed_integer(c, qt) || c_is_float(c, qt)) { // float and signed integer overflow is undefined behavior. return false; @@ -782,37 +772,37 @@ static bool qual_type_has_wrapping_overflow(Context *c, clang::QualType qt) { } } -static bool type_is_opaque(Context *c, const clang::Type *ty, ZigClangSourceLocation source_loc) { - switch (ty->getTypeClass()) { - case clang::Type::Builtin: { - const clang::BuiltinType *builtin_ty = static_cast(ty); +static bool type_is_opaque(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) { + switch (ZigClangType_getTypeClass(ty)) { + case ZigClangType_Builtin: { + const clang::BuiltinType *builtin_ty = reinterpret_cast(ty); return builtin_ty->getKind() == clang::BuiltinType::Void; } - case clang::Type::Record: { - const clang::RecordType *record_ty = static_cast(ty); + case ZigClangType_Record: { + const clang::RecordType *record_ty = reinterpret_cast(ty); return record_ty->getDecl()->getDefinition() == nullptr; } - case clang::Type::Elaborated: { - const clang::ElaboratedType *elaborated_ty = static_cast(ty); - return type_is_opaque(c, elaborated_ty->getNamedType().getTypePtr(), source_loc); + case ZigClangType_Elaborated: { + const clang::ElaboratedType *elaborated_ty = reinterpret_cast(ty); + ZigClangQualType qt = bitcast(elaborated_ty->getNamedType()); + return type_is_opaque(c, ZigClangQualType_getTypePtr(qt), source_loc); } - case clang::Type::Typedef: { + case ZigClangType_Typedef: { const ZigClangTypedefType *typedef_ty = reinterpret_cast(ty); const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl); - clang::QualType qt = bitcast(underlying_type); - return type_is_opaque(c, qt.getTypePtr(), source_loc); + return type_is_opaque(c, ZigClangQualType_getTypePtr(underlying_type), source_loc); } default: return false; } } -static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLocation source_loc) { - switch (ty->getTypeClass()) { - case clang::Type::Builtin: +static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) { + switch (ZigClangType_getTypeClass(ty)) { + case ZigClangType_Builtin: { - const clang::BuiltinType *builtin_ty = static_cast(ty); + const clang::BuiltinType *builtin_ty = reinterpret_cast(ty); switch (builtin_ty->getKind()) { case clang::BuiltinType::Void: return trans_create_node_symbol_str(c, "c_void"); @@ -955,10 +945,10 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca } break; } - case clang::Type::Pointer: + case ZigClangType_Pointer: { - const clang::PointerType *pointer_ty = static_cast(ty); - clang::QualType child_qt = pointer_ty->getPointeeType(); + const clang::PointerType *pointer_ty = reinterpret_cast(ty); + ZigClangQualType child_qt = bitcast(pointer_ty->getPointeeType()); AstNode *child_node = trans_qual_type(c, child_qt, source_loc); if (child_node == nullptr) { emit_warning(c, source_loc, "pointer to unsupported type"); @@ -969,29 +959,33 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca return trans_create_node_prefix_op(c, PrefixOpOptional, child_node); } - if (type_is_opaque(c, child_qt.getTypePtr(), source_loc)) { - AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(), - child_qt.isVolatileQualified(), child_node, PtrLenSingle); + if (type_is_opaque(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) { + AstNode *pointer_node = trans_create_node_ptr_type(c, + ZigClangQualType_isConstQualified(child_qt), + ZigClangQualType_isVolatileQualified(child_qt), + child_node, PtrLenSingle); return trans_create_node_prefix_op(c, PrefixOpOptional, pointer_node); } else { - return trans_create_node_ptr_type(c, child_qt.isConstQualified(), - child_qt.isVolatileQualified(), child_node, PtrLenC); + return trans_create_node_ptr_type(c, + ZigClangQualType_isConstQualified(child_qt), + ZigClangQualType_isVolatileQualified(child_qt), + child_node, PtrLenC); } } - case clang::Type::Typedef: + case ZigClangType_Typedef: { const ZigClangTypedefType *typedef_ty = reinterpret_cast(ty); const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); return resolve_typedef_decl(c, typedef_decl); } - case clang::Type::Elaborated: + case ZigClangType_Elaborated: { - const clang::ElaboratedType *elaborated_ty = static_cast(ty); + const clang::ElaboratedType *elaborated_ty = reinterpret_cast(ty); switch (elaborated_ty->getKeyword()) { case clang::ETK_Struct: case clang::ETK_Enum: case clang::ETK_Union: - return trans_qual_type(c, elaborated_ty->getNamedType(), source_loc); + return trans_qual_type(c, bitcast(elaborated_ty->getNamedType()), source_loc); case clang::ETK_Interface: case clang::ETK_Class: case clang::ETK_Typename: @@ -1000,10 +994,10 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca return nullptr; } } - case clang::Type::FunctionProto: - case clang::Type::FunctionNoProto: + case ZigClangType_FunctionProto: + case ZigClangType_FunctionNoProto: { - const clang::FunctionType *fn_ty = static_cast(ty); + const clang::FunctionType *fn_ty = reinterpret_cast(ty); AstNode *proto_node = trans_create_node(c, NodeTypeFnProto); switch (fn_ty->getCallConv()) { @@ -1067,14 +1061,14 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca if (fn_ty->getNoReturnAttr()) { proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn"); } else { - proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_ty->getReturnType(), + proto_node->data.fn_proto.return_type = trans_qual_type(c, bitcast(fn_ty->getReturnType()), source_loc); if (proto_node->data.fn_proto.return_type == nullptr) { emit_warning(c, source_loc, "unsupported function proto return type"); return nullptr; } // convert c_void to actual void (only for return type) - // we do want to look at the AstNode instead of clang::QualType, because + // we do want to look at the AstNode instead of ZigClangQualType, because // if they do something like: // typedef Foo void; // void foo(void) -> Foo; @@ -1090,17 +1084,17 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca proto_node->data.fn_proto.name = buf_create_from_str(fn_name); } - if (ty->getTypeClass() == clang::Type::FunctionNoProto) { + if (ZigClangType_getTypeClass(ty) == ZigClangType_FunctionNoProto) { return proto_node; } - const clang::FunctionProtoType *fn_proto_ty = static_cast(ty); + const clang::FunctionProtoType *fn_proto_ty = reinterpret_cast(ty); proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic(); size_t param_count = fn_proto_ty->getNumParams(); for (size_t i = 0; i < param_count; i += 1) { - clang::QualType qt = fn_proto_ty->getParamType(i); + ZigClangQualType qt = bitcast(fn_proto_ty->getParamType(i)); AstNode *param_type_node = trans_qual_type(c, qt, source_loc); if (param_type_node == nullptr) { @@ -1114,7 +1108,7 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca if (param_name != nullptr) { param_node->data.param_decl.name = buf_create_from_str(param_name); } - param_node->data.param_decl.is_noalias = qt.isRestrictQualified(); + param_node->data.param_decl.is_noalias = ZigClangQualType_isRestrictQualified(qt); param_node->data.param_decl.type = param_type_node; proto_node->data.fn_proto.params.append(param_node); } @@ -1123,20 +1117,20 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca return proto_node; } - case clang::Type::Record: + case ZigClangType_Record: { const ZigClangRecordType *record_ty = reinterpret_cast(ty); return resolve_record_decl(c, ZigClangRecordType_getDecl(record_ty)); } - case clang::Type::Enum: + case ZigClangType_Enum: { const ZigClangEnumType *enum_ty = reinterpret_cast(ty); return resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty)); } - case clang::Type::ConstantArray: + case ZigClangType_ConstantArray: { - const clang::ConstantArrayType *const_arr_ty = static_cast(ty); - AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc); + const clang::ConstantArrayType *const_arr_ty = reinterpret_cast(ty); + AstNode *child_type_node = trans_qual_type(c, bitcast(const_arr_ty->getElementType()), source_loc); if (child_type_node == nullptr) { emit_warning(c, source_loc, "unresolved array element type"); return nullptr; @@ -1145,76 +1139,78 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLoca AstNode *size_node = trans_create_node_unsigned(c, size); return trans_create_node_array_type(c, size_node, child_type_node); } - case clang::Type::Paren: + case ZigClangType_Paren: { - const clang::ParenType *paren_ty = static_cast(ty); - return trans_qual_type(c, paren_ty->getInnerType(), source_loc); + const clang::ParenType *paren_ty = reinterpret_cast(ty); + return trans_qual_type(c, bitcast(paren_ty->getInnerType()), source_loc); } - case clang::Type::Decayed: + case ZigClangType_Decayed: { - const clang::DecayedType *decayed_ty = static_cast(ty); - return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc); + const clang::DecayedType *decayed_ty = reinterpret_cast(ty); + return trans_qual_type(c, bitcast(decayed_ty->getDecayedType()), source_loc); } - case clang::Type::Attributed: + case ZigClangType_Attributed: { - const clang::AttributedType *attributed_ty = static_cast(ty); - return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc); + const clang::AttributedType *attributed_ty = reinterpret_cast(ty); + return trans_qual_type(c, bitcast(attributed_ty->getEquivalentType()), source_loc); } - case clang::Type::IncompleteArray: + case ZigClangType_IncompleteArray: { - const clang::IncompleteArrayType *incomplete_array_ty = static_cast(ty); - clang::QualType child_qt = incomplete_array_ty->getElementType(); + const clang::IncompleteArrayType *incomplete_array_ty = reinterpret_cast(ty); + ZigClangQualType child_qt = bitcast(incomplete_array_ty->getElementType()); AstNode *child_type_node = trans_qual_type(c, child_qt, source_loc); if (child_type_node == nullptr) { emit_warning(c, source_loc, "unresolved array element type"); return nullptr; } - AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(), - child_qt.isVolatileQualified(), child_type_node, PtrLenC); + AstNode *pointer_node = trans_create_node_ptr_type(c, + ZigClangQualType_isConstQualified(child_qt), + ZigClangQualType_isVolatileQualified(child_qt), + child_type_node, PtrLenC); return pointer_node; } - case clang::Type::BlockPointer: - case clang::Type::LValueReference: - case clang::Type::RValueReference: - case clang::Type::MemberPointer: - case clang::Type::VariableArray: - case clang::Type::DependentSizedArray: - case clang::Type::DependentSizedExtVector: - case clang::Type::Vector: - case clang::Type::ExtVector: - case clang::Type::UnresolvedUsing: - case clang::Type::Adjusted: - case clang::Type::TypeOfExpr: - case clang::Type::TypeOf: - case clang::Type::Decltype: - case clang::Type::UnaryTransform: - case clang::Type::TemplateTypeParm: - case clang::Type::SubstTemplateTypeParm: - case clang::Type::SubstTemplateTypeParmPack: - case clang::Type::TemplateSpecialization: - case clang::Type::Auto: - case clang::Type::InjectedClassName: - case clang::Type::DependentName: - case clang::Type::DependentTemplateSpecialization: - case clang::Type::PackExpansion: - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - case clang::Type::Complex: - case clang::Type::ObjCObjectPointer: - case clang::Type::Atomic: - case clang::Type::Pipe: - case clang::Type::ObjCTypeParam: - case clang::Type::DeducedTemplateSpecialization: - case clang::Type::DependentAddressSpace: - case clang::Type::DependentVector: - emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName()); + case ZigClangType_BlockPointer: + case ZigClangType_LValueReference: + case ZigClangType_RValueReference: + case ZigClangType_MemberPointer: + case ZigClangType_VariableArray: + case ZigClangType_DependentSizedArray: + case ZigClangType_DependentSizedExtVector: + case ZigClangType_Vector: + case ZigClangType_ExtVector: + case ZigClangType_UnresolvedUsing: + case ZigClangType_Adjusted: + case ZigClangType_TypeOfExpr: + case ZigClangType_TypeOf: + case ZigClangType_Decltype: + case ZigClangType_UnaryTransform: + case ZigClangType_TemplateTypeParm: + case ZigClangType_SubstTemplateTypeParm: + case ZigClangType_SubstTemplateTypeParmPack: + case ZigClangType_TemplateSpecialization: + case ZigClangType_Auto: + case ZigClangType_InjectedClassName: + case ZigClangType_DependentName: + case ZigClangType_DependentTemplateSpecialization: + case ZigClangType_PackExpansion: + case ZigClangType_ObjCObject: + case ZigClangType_ObjCInterface: + case ZigClangType_Complex: + case ZigClangType_ObjCObjectPointer: + case ZigClangType_Atomic: + case ZigClangType_Pipe: + case ZigClangType_ObjCTypeParam: + case ZigClangType_DeducedTemplateSpecialization: + case ZigClangType_DependentAddressSpace: + case ZigClangType_DependentVector: + emit_warning(c, source_loc, "unsupported type: '%s'", ZigClangType_getTypeClassName(ty)); return nullptr; } zig_unreachable(); } -static AstNode *trans_qual_type(Context *c, clang::QualType qt, ZigClangSourceLocation source_loc) { - return trans_type(c, qt.getTypePtr(), source_loc); +static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc) { + return trans_type(c, ZigClangQualType_getTypePtr(qt), source_loc); } static int trans_compound_stmt_inline(Context *c, TransScope *scope, const clang::CompoundStmt *stmt, @@ -1300,7 +1296,7 @@ static AstNode *trans_constant_expr(Context *c, ResultUsed result_used, const cl emit_warning(c, bitcast(expr->getBeginLoc()), "invalid constant expression"); return nullptr; } - AstNode *node = trans_ap_value(c, &result.Val, expr->getType(), bitcast(expr->getBeginLoc())); + AstNode *node = trans_ap_value(c, &result.Val, bitcast(expr->getType()), bitcast(expr->getBeginLoc())); return maybe_suppress_result(c, result_used, node); } @@ -1410,7 +1406,7 @@ static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransSco } } -static AstNode *trans_create_shift_op(Context *c, TransScope *scope, clang::QualType result_type, +static AstNode *trans_create_shift_op(Context *c, TransScope *scope, ZigClangQualType result_type, clang::Expr *lhs_expr, BinOpType bin_op, clang::Expr *rhs_expr) { ZigClangSourceLocation rhs_location = bitcast(rhs_expr->getBeginLoc()); @@ -1440,12 +1436,12 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS return nullptr; case clang::BO_Mul: { AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), - qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult, + qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeMultWrap : BinOpTypeMult, stmt->getRHS()); return maybe_suppress_result(c, result_used, node); } case clang::BO_Div: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) { + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) { // unsigned/float division uses the operator AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS()); return maybe_suppress_result(c, result_used, node); @@ -1461,7 +1457,7 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS return maybe_suppress_result(c, result_used, fn_call); } case clang::BO_Rem: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) { + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) { // unsigned/float division uses the operator AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeMod, stmt->getRHS()); return maybe_suppress_result(c, result_used, node); @@ -1478,22 +1474,22 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS } case clang::BO_Add: { AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), - qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd, + qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeAddWrap : BinOpTypeAdd, stmt->getRHS()); return maybe_suppress_result(c, result_used, node); } case clang::BO_Sub: { AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), - qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub, + qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeSubWrap : BinOpTypeSub, stmt->getRHS()); return maybe_suppress_result(c, result_used, node); } case clang::BO_Shl: { - AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS()); + AstNode *node = trans_create_shift_op(c, scope, bitcast(stmt->getType()), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS()); return maybe_suppress_result(c, result_used, node); } case clang::BO_Shr: { - AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS()); + AstNode *node = trans_create_shift_op(c, scope, bitcast(stmt->getType()), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS()); return maybe_suppress_result(c, result_used, node); } case clang::BO_LT: { @@ -1581,7 +1577,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result const clang::CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op) { ZigClangSourceLocation rhs_location = bitcast(stmt->getRHS()->getBeginLoc()); - AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location); + AstNode *rhs_type = qual_type_to_log2_int_ref(c, bitcast(stmt->getComputationLHSType()), rhs_location); bool use_intermediate_casts = stmt->getComputationLHSType().getTypePtr() != stmt->getComputationResultType().getTypePtr(); if (!use_intermediate_casts && result_used == ResultUsedNo) { @@ -1626,14 +1622,14 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result // operation_type(*_ref) AstNode *operation_type_cast = trans_c_cast(c, rhs_location, - stmt->getComputationLHSType(), - stmt->getLHS()->getType(), + bitcast(stmt->getComputationLHSType()), + bitcast(stmt->getLHS()->getType()), trans_create_node_ptr_deref(c, trans_create_node_symbol(c, tmp_var_name))); // result_type(... >> u5(rhs)) AstNode *result_type_cast = trans_c_cast(c, rhs_location, - stmt->getComputationResultType(), - stmt->getComputationLHSType(), + bitcast(stmt->getComputationResultType()), + bitcast(stmt->getComputationLHSType()), trans_create_node_bin_op(c, operation_type_cast, bin_op, @@ -1724,7 +1720,7 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use { switch (stmt->getOpcode()) { case clang::BO_MulAssign: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimesWrap, BinOpTypeMultWrap); else return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimes, BinOpTypeMult); @@ -1738,12 +1734,12 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_Cmp"); return nullptr; case clang::BO_AddAssign: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap, BinOpTypeAddWrap); else return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlus, BinOpTypeAdd); case clang::BO_SubAssign: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap, BinOpTypeSubWrap); else return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinus, BinOpTypeSub); @@ -1794,8 +1790,8 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); if (target_node == nullptr) return nullptr; - AstNode *node = trans_c_cast(c, bitcast(stmt->getExprLoc()), stmt->getType(), - stmt->getSubExpr()->getType(), target_node); + AstNode *node = trans_c_cast(c, bitcast(stmt->getExprLoc()), bitcast(stmt->getType()), + bitcast(stmt->getSubExpr()->getType()), target_node); return maybe_suppress_result(c, result_used, node); } case clang::CK_FunctionToPointerDecay: @@ -2106,22 +2102,22 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::UnaryOperator *stmt) { switch (stmt->getOpcode()) { case clang::UO_PostInc: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap); else return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus); case clang::UO_PostDec: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap); else return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus); case clang::UO_PreInc: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap); else return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus); case clang::UO_PreDec: - if (qual_type_has_wrapping_overflow(c, stmt->getType())) + if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap); else return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus); @@ -2137,7 +2133,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue); if (value_node == nullptr) return nullptr; - bool is_fn_ptr = qual_type_is_fn_ptr(stmt->getSubExpr()->getType()); + bool is_fn_ptr = qual_type_is_fn_ptr(bitcast(stmt->getSubExpr()->getType())); if (is_fn_ptr) return value_node; AstNode *unwrapped = trans_create_node_unwrap_null(c, value_node); @@ -2149,7 +2145,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc case clang::UO_Minus: { clang::Expr *op_expr = stmt->getSubExpr(); - if (!qual_type_has_wrapping_overflow(c, op_expr->getType())) { + if (!qual_type_has_wrapping_overflow(c, bitcast(op_expr->getType()))) { AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr); node->data.prefix_op_expr.prefix_op = PrefixOpNegation; @@ -2158,7 +2154,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc return nullptr; return node; - } else if (c_is_unsigned_integer(c, op_expr->getType())) { + } else if (c_is_unsigned_integer(c, bitcast(op_expr->getType()))) { // we gotta emit 0 -% x AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0); @@ -2221,7 +2217,7 @@ static int trans_local_declaration(Context *c, TransScope *scope, const clang::D switch (decl->getKind()) { case clang::Decl::Var: { clang::VarDecl *var_decl = (clang::VarDecl *)decl; - clang::QualType qual_type = var_decl->getTypeSourceInfo()->getType(); + ZigClangQualType qual_type = bitcast(var_decl->getTypeSourceInfo()->getType()); AstNode *init_node = nullptr; if (var_decl->hasInit()) { init_node = trans_expr(c, ResultUsedYes, scope, var_decl->getInit(), TransRValue); @@ -2240,7 +2236,8 @@ static int trans_local_declaration(Context *c, TransScope *scope, const clang::D TransScopeVar *var_scope = trans_scope_var_create(c, scope, c_symbol_name); scope = &var_scope->base; - AstNode *node = trans_create_node_var_decl_local(c, qual_type.isConstQualified(), + AstNode *node = trans_create_node_var_decl_local(c, + ZigClangQualType_isConstQualified(qual_type), var_scope->zig_name, type_node, init_node); scope_block->node->data.block.statements.append(node); @@ -2526,12 +2523,12 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope * } - const clang::Type *ty = get_expr_qual_type_before_implicit_cast(c, expr).getTypePtr(); - auto classs = ty->getTypeClass(); + const ZigClangType *ty = ZigClangQualType_getTypePtr(get_expr_qual_type_before_implicit_cast(c, expr)); + auto classs = ZigClangType_getTypeClass(ty); switch (classs) { - case clang::Type::Builtin: + case ZigClangType_Builtin: { - const clang::BuiltinType *builtin_ty = static_cast(ty); + const clang::BuiltinType *builtin_ty = reinterpret_cast(ty); switch (builtin_ty->getKind()) { case clang::BuiltinType::Bool: case clang::BuiltinType::Char_U: @@ -2657,11 +2654,11 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope * } break; } - case clang::Type::Pointer: + case ZigClangType_Pointer: return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node_unsigned(c, 0)); - case clang::Type::Typedef: + case ZigClangType_Typedef: { const ZigClangTypedefType *typedef_ty = reinterpret_cast(ty); const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty); @@ -2673,19 +2670,20 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope * return res; } - case clang::Type::Enum: + case ZigClangType_Enum: { const ZigClangEnumType *enum_ty = reinterpret_cast(ty); AstNode *enum_type = resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty)); return to_enum_zero_cmp(c, res, enum_type); } - case clang::Type::Elaborated: + case ZigClangType_Elaborated: { - const clang::ElaboratedType *elaborated_ty = static_cast(ty); + const clang::ElaboratedType *elaborated_ty = reinterpret_cast(ty); switch (elaborated_ty->getKeyword()) { case clang::ETK_Enum: { - AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), bitcast(expr->getBeginLoc())); + AstNode *enum_type = trans_qual_type(c, bitcast(elaborated_ty->getNamedType()), + bitcast(expr->getBeginLoc())); return to_enum_zero_cmp(c, res, enum_type); } case clang::ETK_Struct: @@ -2698,48 +2696,48 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope * } } - case clang::Type::FunctionProto: - case clang::Type::Record: - case clang::Type::ConstantArray: - case clang::Type::Paren: - case clang::Type::Decayed: - case clang::Type::Attributed: - case clang::Type::IncompleteArray: - case clang::Type::BlockPointer: - case clang::Type::LValueReference: - case clang::Type::RValueReference: - case clang::Type::MemberPointer: - case clang::Type::VariableArray: - case clang::Type::DependentSizedArray: - case clang::Type::DependentSizedExtVector: - case clang::Type::Vector: - case clang::Type::ExtVector: - case clang::Type::FunctionNoProto: - case clang::Type::UnresolvedUsing: - case clang::Type::Adjusted: - case clang::Type::TypeOfExpr: - case clang::Type::TypeOf: - case clang::Type::Decltype: - case clang::Type::UnaryTransform: - case clang::Type::TemplateTypeParm: - case clang::Type::SubstTemplateTypeParm: - case clang::Type::SubstTemplateTypeParmPack: - case clang::Type::TemplateSpecialization: - case clang::Type::Auto: - case clang::Type::InjectedClassName: - case clang::Type::DependentName: - case clang::Type::DependentTemplateSpecialization: - case clang::Type::PackExpansion: - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - case clang::Type::Complex: - case clang::Type::ObjCObjectPointer: - case clang::Type::Atomic: - case clang::Type::Pipe: - case clang::Type::ObjCTypeParam: - case clang::Type::DeducedTemplateSpecialization: - case clang::Type::DependentAddressSpace: - case clang::Type::DependentVector: + case ZigClangType_FunctionProto: + case ZigClangType_Record: + case ZigClangType_ConstantArray: + case ZigClangType_Paren: + case ZigClangType_Decayed: + case ZigClangType_Attributed: + case ZigClangType_IncompleteArray: + case ZigClangType_BlockPointer: + case ZigClangType_LValueReference: + case ZigClangType_RValueReference: + case ZigClangType_MemberPointer: + case ZigClangType_VariableArray: + case ZigClangType_DependentSizedArray: + case ZigClangType_DependentSizedExtVector: + case ZigClangType_Vector: + case ZigClangType_ExtVector: + case ZigClangType_FunctionNoProto: + case ZigClangType_UnresolvedUsing: + case ZigClangType_Adjusted: + case ZigClangType_TypeOfExpr: + case ZigClangType_TypeOf: + case ZigClangType_Decltype: + case ZigClangType_UnaryTransform: + case ZigClangType_TemplateTypeParm: + case ZigClangType_SubstTemplateTypeParm: + case ZigClangType_SubstTemplateTypeParmPack: + case ZigClangType_TemplateSpecialization: + case ZigClangType_Auto: + case ZigClangType_InjectedClassName: + case ZigClangType_DependentName: + case ZigClangType_DependentTemplateSpecialization: + case ZigClangType_PackExpansion: + case ZigClangType_ObjCObject: + case ZigClangType_ObjCInterface: + case ZigClangType_Complex: + case ZigClangType_ObjCObjectPointer: + case ZigClangType_Atomic: + case ZigClangType_Pipe: + case ZigClangType_ObjCTypeParam: + case ZigClangType_DeducedTemplateSpecialization: + case ZigClangType_DependentAddressSpace: + case ZigClangType_DependentVector: return res; } zig_unreachable(); @@ -2790,7 +2788,7 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope * return nullptr; bool is_ptr = false; - const clang::FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr); + const clang::FunctionProtoType *fn_ty = qual_type_get_fn_proto(bitcast(stmt->getCallee()->getType()), &is_ptr); AstNode *callee_node = nullptr; if (is_ptr && fn_ty) { if (stmt->getCallee()->getStmtClass() == clang::Stmt::ImplicitCastExprClass) { @@ -2824,7 +2822,9 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope * node->data.fn_call_expr.params.append(arg_node); } - if (result_used == ResultUsedNo && fn_ty && !qual_type_canon(fn_ty->getReturnType())->isVoidType()) { + if (result_used == ResultUsedNo && fn_ty && + !ZigClangType_isVoidType(qual_type_canon(bitcast(fn_ty->getReturnType())))) + { node = trans_create_node_bin_op(c, trans_create_node_symbol_str(c, "_"), BinOpTypeAssign, node); } @@ -2871,7 +2871,8 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran if (sub_expr_node == nullptr) return nullptr; - AstNode *cast = trans_c_cast(c, bitcast(stmt->getBeginLoc()), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node); + AstNode *cast = trans_c_cast(c, bitcast(stmt->getBeginLoc()), bitcast(stmt->getType()), + bitcast(stmt->getSubExpr()->getType()), sub_expr_node); if (cast == nullptr) return nullptr; @@ -2881,7 +2882,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::UnaryExprOrTypeTraitExpr *stmt) { - AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), bitcast(stmt->getBeginLoc())); + AstNode *type_node = trans_qual_type(c, bitcast(stmt->getTypeOfArgument()), bitcast(stmt->getBeginLoc())); if (type_node == nullptr) return nullptr; @@ -3858,7 +3859,7 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) { return; } - AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), bitcast(fn_decl->getLocation())); + AstNode *proto_node = trans_qual_type(c, bitcast(fn_decl->getType()), bitcast(fn_decl->getLocation())); if (proto_node == nullptr) { emit_warning(c, bitcast(fn_decl->getLocation()), "unable to resolve prototype of function '%s'", buf_ptr(fn_name)); return; @@ -4003,7 +4004,7 @@ static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl * AstNode *symbol_node = trans_create_node_symbol(c, type_name); c->decl_table.put(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl), symbol_node); - AstNode *type_node = trans_qual_type(c, bitcast(child_qt), ZigClangTypedefNameDecl_getLocation(typedef_decl)); + AstNode *type_node = trans_qual_type(c, child_qt, ZigClangTypedefNameDecl_getLocation(typedef_decl)); if (type_node == nullptr) { emit_warning(c, ZigClangTypedefNameDecl_getLocation(typedef_decl), "typedef %s - unresolved child type", buf_ptr(type_name)); @@ -4059,8 +4060,7 @@ static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl) pure_enum = false; } } - AstNode *tag_int_type = trans_qual_type(c, - bitcast(ZigClangEnumDecl_getIntegerType(enum_decl)), + AstNode *tag_int_type = trans_qual_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), ZigClangEnumDecl_getLocation(enum_decl)); assert(tag_int_type); @@ -4070,8 +4070,8 @@ static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl) // TODO only emit this tag type if the enum tag type is not the default. // I don't know what the default is, need to figure out how clang is deciding. // it appears to at least be different across gcc/msvc - if (!c_is_builtin_type(c, bitcast(ZigClangEnumDecl_getIntegerType(enum_decl)), clang::BuiltinType::UInt) && - !c_is_builtin_type(c, bitcast(ZigClangEnumDecl_getIntegerType(enum_decl)), clang::BuiltinType::Int)) + if (!c_is_builtin_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), clang::BuiltinType::UInt) && + !c_is_builtin_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), clang::BuiltinType::Int)) { enum_node->data.container_decl.init_arg_expr = tag_int_type; } @@ -4209,7 +4209,7 @@ static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record AstNode *field_node = trans_create_node(c, NodeTypeStructField); field_node->data.struct_field.name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)field_decl)); - field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), + field_node->data.struct_field.type = trans_qual_type(c, bitcast(field_decl->getType()), bitcast(field_decl->getLocation())); if (field_node->data.struct_field.type == nullptr) { @@ -4233,7 +4233,7 @@ static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record } } -static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, ZigClangSourceLocation source_loc) { +static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, ZigClangQualType qt, ZigClangSourceLocation source_loc) { switch (ap_value->getKind()) { case clang::APValue::Int: return trans_create_node_apint(c, ap_value->getInt()); @@ -4253,7 +4253,8 @@ static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::Qual init_node->data.container_init_expr.type = arr_type_node; init_node->data.container_init_expr.kind = ContainerInitKindArray; - clang::QualType child_qt = qt.getTypePtr()->getAsArrayTypeUnsafe()->getElementType(); + const clang::Type *qt_type = reinterpret_cast(ZigClangQualType_getTypePtr(qt)); + ZigClangQualType child_qt = bitcast(qt_type->getAsArrayTypeUnsafe()->getElementType()); for (size_t i = 0; i < init_count; i += 1) { clang::APValue &elem_ap_val = ap_value->getArrayInitializedElt(i); @@ -4347,7 +4348,7 @@ static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) { return; } - clang::QualType qt = var_decl->getType(); + ZigClangQualType qt = bitcast(var_decl->getType()); AstNode *var_type = trans_qual_type(c, qt, bitcast(var_decl->getLocation())); if (var_type == nullptr) { emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - unresolved type", buf_ptr(name)); @@ -4356,7 +4357,7 @@ static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) { bool is_extern = var_decl->hasExternalStorage(); bool is_static = var_decl->isFileVarDecl(); - bool is_const = qt.isConstQualified(); + bool is_const = ZigClangQualType_isConstQualified(qt); if (is_static && !is_extern) { AstNode *init_node; diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 4f50c5d3d3..265a37d82a 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -28,41 +28,41 @@ #endif // Detect additions to the enum -void zig2clang_BO(ZigClangBO op) { +void zig2clang_BO(clang::BinaryOperatorKind op) { switch (op) { - case ZigClangBO_PtrMemD: - case ZigClangBO_PtrMemI: - case ZigClangBO_Cmp: - case ZigClangBO_Mul: - case ZigClangBO_Div: - case ZigClangBO_Rem: - case ZigClangBO_Add: - case ZigClangBO_Sub: - case ZigClangBO_Shl: - case ZigClangBO_Shr: - case ZigClangBO_LT: - case ZigClangBO_GT: - case ZigClangBO_LE: - case ZigClangBO_GE: - case ZigClangBO_EQ: - case ZigClangBO_NE: - case ZigClangBO_And: - case ZigClangBO_Xor: - case ZigClangBO_Or: - case ZigClangBO_LAnd: - case ZigClangBO_LOr: - case ZigClangBO_Assign: - case ZigClangBO_Comma: - case ZigClangBO_MulAssign: - case ZigClangBO_DivAssign: - case ZigClangBO_RemAssign: - case ZigClangBO_AddAssign: - case ZigClangBO_SubAssign: - case ZigClangBO_ShlAssign: - case ZigClangBO_ShrAssign: - case ZigClangBO_AndAssign: - case ZigClangBO_XorAssign: - case ZigClangBO_OrAssign: + case clang::BO_PtrMemD: + case clang::BO_PtrMemI: + case clang::BO_Cmp: + case clang::BO_Mul: + case clang::BO_Div: + case clang::BO_Rem: + case clang::BO_Add: + case clang::BO_Sub: + case clang::BO_Shl: + case clang::BO_Shr: + case clang::BO_LT: + case clang::BO_GT: + case clang::BO_LE: + case clang::BO_GE: + case clang::BO_EQ: + case clang::BO_NE: + case clang::BO_And: + case clang::BO_Xor: + case clang::BO_Or: + case clang::BO_LAnd: + case clang::BO_LOr: + case clang::BO_Assign: + case clang::BO_Comma: + case clang::BO_MulAssign: + case clang::BO_DivAssign: + case clang::BO_RemAssign: + case clang::BO_AddAssign: + case clang::BO_SubAssign: + case clang::BO_ShlAssign: + case clang::BO_ShrAssign: + case clang::BO_AndAssign: + case clang::BO_XorAssign: + case clang::BO_OrAssign: break; } } @@ -102,22 +102,22 @@ static_assert((clang::BinaryOperatorKind)ZigClangBO_Xor == clang::BO_Xor, ""); static_assert((clang::BinaryOperatorKind)ZigClangBO_XorAssign == clang::BO_XorAssign, ""); // This function detects additions to the enum -void zig2clang_UO(ZigClangUO op) { +void zig2clang_UO(clang::UnaryOperatorKind op) { switch (op) { - case ZigClangUO_AddrOf: - case ZigClangUO_Coawait: - case ZigClangUO_Deref: - case ZigClangUO_Extension: - case ZigClangUO_Imag: - case ZigClangUO_LNot: - case ZigClangUO_Minus: - case ZigClangUO_Not: - case ZigClangUO_Plus: - case ZigClangUO_PostDec: - case ZigClangUO_PostInc: - case ZigClangUO_PreDec: - case ZigClangUO_PreInc: - case ZigClangUO_Real: + case clang::UO_AddrOf: + case clang::UO_Coawait: + case clang::UO_Deref: + case clang::UO_Extension: + case clang::UO_Imag: + case clang::UO_LNot: + case clang::UO_Minus: + case clang::UO_Not: + case clang::UO_Plus: + case clang::UO_PostDec: + case clang::UO_PostInc: + case clang::UO_PreDec: + case clang::UO_PreInc: + case clang::UO_Real: break; } } @@ -137,6 +137,108 @@ static_assert((clang::UnaryOperatorKind)ZigClangUO_PreDec == clang::UO_PreDec, " static_assert((clang::UnaryOperatorKind)ZigClangUO_PreInc == clang::UO_PreInc, ""); static_assert((clang::UnaryOperatorKind)ZigClangUO_Real == clang::UO_Real, ""); +void zig2clang_TypeClass(clang::Type::TypeClass ty) { + switch (ty) { + case clang::Type::Builtin: + case clang::Type::Complex: + case clang::Type::Pointer: + case clang::Type::BlockPointer: + case clang::Type::LValueReference: + case clang::Type::RValueReference: + case clang::Type::MemberPointer: + case clang::Type::ConstantArray: + case clang::Type::IncompleteArray: + case clang::Type::VariableArray: + case clang::Type::DependentSizedArray: + case clang::Type::DependentSizedExtVector: + case clang::Type::DependentAddressSpace: + case clang::Type::Vector: + case clang::Type::DependentVector: + case clang::Type::ExtVector: + case clang::Type::FunctionProto: + case clang::Type::FunctionNoProto: + case clang::Type::UnresolvedUsing: + case clang::Type::Paren: + case clang::Type::Typedef: + case clang::Type::Adjusted: + case clang::Type::Decayed: + case clang::Type::TypeOfExpr: + case clang::Type::TypeOf: + case clang::Type::Decltype: + case clang::Type::UnaryTransform: + case clang::Type::Record: + case clang::Type::Enum: + case clang::Type::Elaborated: + case clang::Type::Attributed: + case clang::Type::TemplateTypeParm: + case clang::Type::SubstTemplateTypeParm: + case clang::Type::SubstTemplateTypeParmPack: + case clang::Type::TemplateSpecialization: + case clang::Type::Auto: + case clang::Type::DeducedTemplateSpecialization: + case clang::Type::InjectedClassName: + case clang::Type::DependentName: + case clang::Type::DependentTemplateSpecialization: + case clang::Type::PackExpansion: + case clang::Type::ObjCTypeParam: + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + case clang::Type::ObjCObjectPointer: + case clang::Type::Pipe: + case clang::Type::Atomic: + break; + } +} + +static_assert((clang::Type::TypeClass)ZigClangType_Builtin == clang::Type::Builtin, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Complex == clang::Type::Complex, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Pointer == clang::Type::Pointer, ""); +static_assert((clang::Type::TypeClass)ZigClangType_BlockPointer == clang::Type::BlockPointer, ""); +static_assert((clang::Type::TypeClass)ZigClangType_LValueReference == clang::Type::LValueReference, ""); +static_assert((clang::Type::TypeClass)ZigClangType_RValueReference == clang::Type::RValueReference, ""); +static_assert((clang::Type::TypeClass)ZigClangType_MemberPointer == clang::Type::MemberPointer, ""); +static_assert((clang::Type::TypeClass)ZigClangType_ConstantArray == clang::Type::ConstantArray, ""); +static_assert((clang::Type::TypeClass)ZigClangType_IncompleteArray == clang::Type::IncompleteArray, ""); +static_assert((clang::Type::TypeClass)ZigClangType_VariableArray == clang::Type::VariableArray, ""); +static_assert((clang::Type::TypeClass)ZigClangType_DependentSizedArray == clang::Type::DependentSizedArray, ""); +static_assert((clang::Type::TypeClass)ZigClangType_DependentSizedExtVector == clang::Type::DependentSizedExtVector, ""); +static_assert((clang::Type::TypeClass)ZigClangType_DependentAddressSpace == clang::Type::DependentAddressSpace, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Vector == clang::Type::Vector, ""); +static_assert((clang::Type::TypeClass)ZigClangType_DependentVector == clang::Type::DependentVector, ""); +static_assert((clang::Type::TypeClass)ZigClangType_ExtVector == clang::Type::ExtVector, ""); +static_assert((clang::Type::TypeClass)ZigClangType_FunctionProto == clang::Type::FunctionProto, ""); +static_assert((clang::Type::TypeClass)ZigClangType_FunctionNoProto == clang::Type::FunctionNoProto, ""); +static_assert((clang::Type::TypeClass)ZigClangType_UnresolvedUsing == clang::Type::UnresolvedUsing, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Paren == clang::Type::Paren, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Typedef == clang::Type::Typedef, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Adjusted == clang::Type::Adjusted, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Decayed == clang::Type::Decayed, ""); +static_assert((clang::Type::TypeClass)ZigClangType_TypeOfExpr == clang::Type::TypeOfExpr, ""); +static_assert((clang::Type::TypeClass)ZigClangType_TypeOf == clang::Type::TypeOf, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Decltype == clang::Type::Decltype, ""); +static_assert((clang::Type::TypeClass)ZigClangType_UnaryTransform == clang::Type::UnaryTransform, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Record == clang::Type::Record, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Enum == clang::Type::Enum, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Elaborated == clang::Type::Elaborated, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Attributed == clang::Type::Attributed, ""); +static_assert((clang::Type::TypeClass)ZigClangType_TemplateTypeParm == clang::Type::TemplateTypeParm, ""); +static_assert((clang::Type::TypeClass)ZigClangType_SubstTemplateTypeParm == clang::Type::SubstTemplateTypeParm, ""); +static_assert((clang::Type::TypeClass)ZigClangType_SubstTemplateTypeParmPack == clang::Type::SubstTemplateTypeParmPack, ""); +static_assert((clang::Type::TypeClass)ZigClangType_TemplateSpecialization == clang::Type::TemplateSpecialization, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Auto == clang::Type::Auto, ""); +static_assert((clang::Type::TypeClass)ZigClangType_DeducedTemplateSpecialization == clang::Type::DeducedTemplateSpecialization, ""); +static_assert((clang::Type::TypeClass)ZigClangType_InjectedClassName == clang::Type::InjectedClassName, ""); +static_assert((clang::Type::TypeClass)ZigClangType_DependentName == clang::Type::DependentName, ""); +static_assert((clang::Type::TypeClass)ZigClangType_DependentTemplateSpecialization == clang::Type::DependentTemplateSpecialization, ""); +static_assert((clang::Type::TypeClass)ZigClangType_PackExpansion == clang::Type::PackExpansion, ""); +static_assert((clang::Type::TypeClass)ZigClangType_ObjCTypeParam == clang::Type::ObjCTypeParam, ""); +static_assert((clang::Type::TypeClass)ZigClangType_ObjCObject == clang::Type::ObjCObject, ""); +static_assert((clang::Type::TypeClass)ZigClangType_ObjCInterface == clang::Type::ObjCInterface, ""); +static_assert((clang::Type::TypeClass)ZigClangType_ObjCObjectPointer == clang::Type::ObjCObjectPointer, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Pipe == clang::Type::Pipe, ""); +static_assert((clang::Type::TypeClass)ZigClangType_Atomic == clang::Type::Atomic, ""); + + static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), ""); static ZigClangSourceLocation bitcast(clang::SourceLocation src) { ZigClangSourceLocation dest; @@ -304,3 +406,65 @@ ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(const ZigClangTypedef clang::QualType ty = casted->getUnderlyingType(); return bitcast(ty); } + +ZigClangQualType ZigClangQualType_getCanonicalType(ZigClangQualType self) { + clang::QualType qt = bitcast(self); + return bitcast(qt.getCanonicalType()); +} + +const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType self) { + clang::QualType qt = bitcast(self); + const clang::Type *ty = qt.getTypePtr(); + return reinterpret_cast(ty); +} + +void ZigClangQualType_addConst(ZigClangQualType *self) { + reinterpret_cast(self)->addConst(); +} + +bool ZigClangQualType_eq(ZigClangQualType zig_t1, ZigClangQualType zig_t2) { + clang::QualType t1 = bitcast(zig_t1); + clang::QualType t2 = bitcast(zig_t2); + if (t1.isConstQualified() != t2.isConstQualified()) { + return false; + } + if (t1.isVolatileQualified() != t2.isVolatileQualified()) { + return false; + } + if (t1.isRestrictQualified() != t2.isRestrictQualified()) { + return false; + } + return t1.getTypePtr() == t2.getTypePtr(); +} + +bool ZigClangQualType_isConstQualified(ZigClangQualType self) { + clang::QualType qt = bitcast(self); + return qt.isConstQualified(); +} + +bool ZigClangQualType_isVolatileQualified(ZigClangQualType self) { + clang::QualType qt = bitcast(self); + return qt.isVolatileQualified(); +} + +bool ZigClangQualType_isRestrictQualified(ZigClangQualType self) { + clang::QualType qt = bitcast(self); + return qt.isRestrictQualified(); +} + +ZigClangTypeClass ZigClangType_getTypeClass(const ZigClangType *self) { + auto casted = reinterpret_cast(self); + clang::Type::TypeClass tc = casted->getTypeClass(); + return (ZigClangTypeClass)tc; +} + +bool ZigClangType_isVoidType(const ZigClangType *self) { + auto casted = reinterpret_cast(self); + return casted->isVoidType(); +} + +const char *ZigClangType_getTypeClassName(const ZigClangType *self) { + auto casted = reinterpret_cast(self); + return casted->getTypeClassName(); +} + diff --git a/src/zig_clang.h b/src/zig_clang.h index c534addf9e..1e96e9a8e7 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -150,6 +150,56 @@ enum ZigClangUO { ZigClangUO_Coawait, }; +enum ZigClangTypeClass { + 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, +}; + //struct ZigClangCC_AAPCS; //struct ZigClangCC_AAPCS_VFP; //struct ZigClangCC_C; @@ -285,4 +335,16 @@ ZIG_EXTERN_C bool ZigClangSourceLocation_eq(ZigClangSourceLocation a, ZigClangSo 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); #endif From 6284a4c534771797406ceb945e5b7985d591d62b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 12 Apr 2019 03:56:38 -0400 Subject: [PATCH 041/285] translate-c: move some code to the C API See #1964 --- src/translate_c.cpp | 412 ++++++++++++++++++++++---------------------- src/zig_clang.cpp | 405 ++++++++++++++++++++++++++++++++++++++++++- src/zig_clang.h | 200 +++++++++++++++++++++ 3 files changed, 810 insertions(+), 207 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 84770844b7..006b4e330f 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -509,11 +509,11 @@ static const ZigClangType *qual_type_canon(ZigClangQualType qt) { static ZigClangQualType get_expr_qual_type(Context *c, const clang::Expr *expr) { // String literals in C are `char *` but they should really be `const char *`. - if (expr->getStmtClass() == clang::Stmt::ImplicitCastExprClass) { + if ((ZigClangStmtClass)expr->getStmtClass() == ZigClangStmt_ImplicitCastExprClass) { const clang::ImplicitCastExpr *cast_expr = static_cast(expr); if (cast_expr->getCastKind() == clang::CK_ArrayToPointerDecay) { const clang::Expr *sub_expr = cast_expr->getSubExpr(); - if (sub_expr->getStmtClass() == clang::Stmt::StringLiteralClass) { + if ((ZigClangStmtClass)sub_expr->getStmtClass() == ZigClangStmt_StringLiteralClass) { ZigClangQualType array_qt = bitcast(sub_expr->getType()); const clang::ArrayType *array_type = reinterpret_cast( ZigClangQualType_getTypePtr(array_qt)); @@ -527,7 +527,7 @@ static ZigClangQualType get_expr_qual_type(Context *c, const clang::Expr *expr) } static ZigClangQualType get_expr_qual_type_before_implicit_cast(Context *c, const clang::Expr *expr) { - if (expr->getStmtClass() == clang::Stmt::ImplicitCastExprClass) { + if ((ZigClangStmtClass)expr->getStmtClass() == ZigClangStmt_ImplicitCastExprClass) { const clang::ImplicitCastExpr *cast_expr = static_cast(expr); return get_expr_qual_type(c, cast_expr->getSubExpr()); } @@ -2791,10 +2791,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope * const clang::FunctionProtoType *fn_ty = qual_type_get_fn_proto(bitcast(stmt->getCallee()->getType()), &is_ptr); AstNode *callee_node = nullptr; if (is_ptr && fn_ty) { - if (stmt->getCallee()->getStmtClass() == clang::Stmt::ImplicitCastExprClass) { + if ((ZigClangStmtClass)stmt->getCallee()->getStmtClass() == ZigClangStmt_ImplicitCastExprClass) { const clang::ImplicitCastExpr *implicit_cast = static_cast(stmt->getCallee()); if (implicit_cast->getCastKind() == clang::CK_FunctionToPointerDecay) { - if (implicit_cast->getSubExpr()->getStmtClass() == clang::Stmt::DeclRefExprClass) { + if ((ZigClangStmtClass)implicit_cast->getSubExpr()->getStmtClass() == ZigClangStmt_DeclRefExprClass) { const clang::DeclRefExpr *decl_ref = static_cast(implicit_cast->getSubExpr()); const clang::Decl *decl = decl_ref->getFoundDecl(); if (decl->getKind() == clang::Decl::Function) { @@ -2898,7 +2898,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang: AstNode *body_node; TransScope *child_scope; - if (stmt->getBody()->getStmtClass() == clang::Stmt::CompoundStmtClass) { + if ((ZigClangStmtClass)stmt->getBody()->getStmtClass() == ZigClangStmt_CompoundStmtClass) { // there's already a block in C, so we'll append our condition to it. // c: do { // c: a; @@ -3051,7 +3051,7 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const cl AstNode *body_node; const clang::Stmt *body_stmt = stmt->getBody(); - if (body_stmt->getStmtClass() == clang::Stmt::CompoundStmtClass) { + if ((ZigClangStmtClass)body_stmt->getStmtClass() == ZigClangStmt_CompoundStmtClass) { if (trans_compound_stmt_inline(c, &switch_scope->base, (const clang::CompoundStmt *)body_stmt, block_scope->node, nullptr)) { @@ -3224,40 +3224,40 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st AstNode **out_node, TransScope **out_child_scope, TransScope **out_node_scope) { - clang::Stmt::StmtClass sc = stmt->getStmtClass(); + ZigClangStmtClass sc = (ZigClangStmtClass)stmt->getStmtClass(); switch (sc) { - case clang::Stmt::ReturnStmtClass: + case ZigClangStmt_ReturnStmtClass: return wrap_stmt(out_node, out_child_scope, scope, trans_return_stmt(c, scope, (const clang::ReturnStmt *)stmt)); - case clang::Stmt::CompoundStmtClass: + case ZigClangStmt_CompoundStmtClass: return wrap_stmt(out_node, out_child_scope, scope, trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope)); - case clang::Stmt::IntegerLiteralClass: + case ZigClangStmt_IntegerLiteralClass: return wrap_stmt(out_node, out_child_scope, scope, trans_integer_literal(c, result_used, (const clang::IntegerLiteral *)stmt)); - case clang::Stmt::ConditionalOperatorClass: + case ZigClangStmt_ConditionalOperatorClass: return wrap_stmt(out_node, out_child_scope, scope, trans_conditional_operator(c, result_used, scope, (const clang::ConditionalOperator *)stmt)); - case clang::Stmt::BinaryOperatorClass: + case ZigClangStmt_BinaryOperatorClass: return wrap_stmt(out_node, out_child_scope, scope, trans_binary_operator(c, result_used, scope, (const clang::BinaryOperator *)stmt)); - case clang::Stmt::CompoundAssignOperatorClass: + case ZigClangStmt_CompoundAssignOperatorClass: return wrap_stmt(out_node, out_child_scope, scope, trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt)); - case clang::Stmt::ImplicitCastExprClass: + case ZigClangStmt_ImplicitCastExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_implicit_cast_expr(c, result_used, scope, (const clang::ImplicitCastExpr *)stmt)); - case clang::Stmt::DeclRefExprClass: + case ZigClangStmt_DeclRefExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_decl_ref_expr(c, scope, (const clang::DeclRefExpr *)stmt, lrvalue)); - case clang::Stmt::UnaryOperatorClass: + case ZigClangStmt_UnaryOperatorClass: return wrap_stmt(out_node, out_child_scope, scope, trans_unary_operator(c, result_used, scope, (const clang::UnaryOperator *)stmt)); - case clang::Stmt::DeclStmtClass: + case ZigClangStmt_DeclStmtClass: return trans_local_declaration(c, scope, (const clang::DeclStmt *)stmt, out_node, out_child_scope); - case clang::Stmt::DoStmtClass: - case clang::Stmt::WhileStmtClass: { - AstNode *while_node = sc == clang::Stmt::DoStmtClass + case ZigClangStmt_DoStmtClass: + case ZigClangStmt_WhileStmtClass: { + AstNode *while_node = sc == ZigClangStmt_DoStmtClass ? trans_do_loop(c, scope, (const clang::DoStmt *)stmt) : trans_while_loop(c, scope, (const clang::WhileStmt *)stmt); @@ -3270,559 +3270,559 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st return wrap_stmt(out_node, out_child_scope, scope, while_node); } - case clang::Stmt::IfStmtClass: + case ZigClangStmt_IfStmtClass: return wrap_stmt(out_node, out_child_scope, scope, trans_if_statement(c, scope, (const clang::IfStmt *)stmt)); - case clang::Stmt::CallExprClass: + case ZigClangStmt_CallExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt)); - case clang::Stmt::NullStmtClass: + case ZigClangStmt_NullStmtClass: *out_node = trans_create_node(c, NodeTypeBlock); *out_child_scope = scope; return ErrorNone; - case clang::Stmt::MemberExprClass: + case ZigClangStmt_MemberExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_member_expr(c, result_used, scope, (const clang::MemberExpr *)stmt)); - case clang::Stmt::ArraySubscriptExprClass: + case ZigClangStmt_ArraySubscriptExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_array_subscript_expr(c, result_used, scope, (const clang::ArraySubscriptExpr *)stmt)); - case clang::Stmt::CStyleCastExprClass: + case ZigClangStmt_CStyleCastExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue)); - case clang::Stmt::UnaryExprOrTypeTraitExprClass: + case ZigClangStmt_UnaryExprOrTypeTraitExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_unary_expr_or_type_trait_expr(c, result_used, scope, (const clang::UnaryExprOrTypeTraitExpr *)stmt)); - case clang::Stmt::ForStmtClass: { + case ZigClangStmt_ForStmtClass: { AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt); return wrap_stmt(out_node, out_child_scope, scope, node); } - case clang::Stmt::StringLiteralClass: + case ZigClangStmt_StringLiteralClass: return wrap_stmt(out_node, out_child_scope, scope, trans_string_literal(c, result_used, scope, (const clang::StringLiteral *)stmt)); - case clang::Stmt::BreakStmtClass: + case ZigClangStmt_BreakStmtClass: return wrap_stmt(out_node, out_child_scope, scope, trans_break_stmt(c, scope, (const clang::BreakStmt *)stmt)); - case clang::Stmt::ContinueStmtClass: + case ZigClangStmt_ContinueStmtClass: return wrap_stmt(out_node, out_child_scope, scope, trans_continue_stmt(c, scope, (const clang::ContinueStmt *)stmt)); - case clang::Stmt::ParenExprClass: + case ZigClangStmt_ParenExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_expr(c, result_used, scope, ((const clang::ParenExpr*)stmt)->getSubExpr(), lrvalue)); - case clang::Stmt::SwitchStmtClass: + case ZigClangStmt_SwitchStmtClass: return wrap_stmt(out_node, out_child_scope, scope, trans_switch_stmt(c, scope, (const clang::SwitchStmt *)stmt)); - case clang::Stmt::CaseStmtClass: + case ZigClangStmt_CaseStmtClass: return trans_switch_case(c, scope, (const clang::CaseStmt *)stmt, out_node, out_child_scope); - case clang::Stmt::DefaultStmtClass: + case ZigClangStmt_DefaultStmtClass: return trans_switch_default(c, scope, (const clang::DefaultStmt *)stmt, out_node, out_child_scope); - case clang::Stmt::ConstantExprClass: + case ZigClangStmt_ConstantExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_constant_expr(c, result_used, (const clang::ConstantExpr *)stmt)); - case clang::Stmt::PredefinedExprClass: + case ZigClangStmt_PredefinedExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_predefined_expr(c, result_used, scope, (const clang::PredefinedExpr *)stmt)); - case clang::Stmt::StmtExprClass: + case ZigClangStmt_StmtExprClass: return wrap_stmt(out_node, out_child_scope, scope, trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope)); - case clang::Stmt::NoStmtClass: + case ZigClangStmt_NoStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NoStmtClass"); return ErrorUnexpected; - case clang::Stmt::GCCAsmStmtClass: + case ZigClangStmt_GCCAsmStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GCCAsmStmtClass"); return ErrorUnexpected; - case clang::Stmt::MSAsmStmtClass: + case ZigClangStmt_MSAsmStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSAsmStmtClass"); return ErrorUnexpected; - case clang::Stmt::AttributedStmtClass: + case ZigClangStmt_AttributedStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AttributedStmtClass"); return ErrorUnexpected; - case clang::Stmt::CXXCatchStmtClass: + case ZigClangStmt_CXXCatchStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXCatchStmtClass"); return ErrorUnexpected; - case clang::Stmt::CXXForRangeStmtClass: + case ZigClangStmt_CXXForRangeStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXForRangeStmtClass"); return ErrorUnexpected; - case clang::Stmt::CXXTryStmtClass: + case ZigClangStmt_CXXTryStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTryStmtClass"); return ErrorUnexpected; - case clang::Stmt::CapturedStmtClass: + case ZigClangStmt_CapturedStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CapturedStmtClass"); return ErrorUnexpected; - case clang::Stmt::CoreturnStmtClass: + case ZigClangStmt_CoreturnStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoreturnStmtClass"); return ErrorUnexpected; - case clang::Stmt::CoroutineBodyStmtClass: + case ZigClangStmt_CoroutineBodyStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoroutineBodyStmtClass"); return ErrorUnexpected; - case clang::Stmt::BinaryConditionalOperatorClass: + case ZigClangStmt_BinaryConditionalOperatorClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BinaryConditionalOperatorClass"); return ErrorUnexpected; - case clang::Stmt::AddrLabelExprClass: + case ZigClangStmt_AddrLabelExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AddrLabelExprClass"); return ErrorUnexpected; - case clang::Stmt::ArrayInitIndexExprClass: + case ZigClangStmt_ArrayInitIndexExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayInitIndexExprClass"); return ErrorUnexpected; - case clang::Stmt::ArrayInitLoopExprClass: + case ZigClangStmt_ArrayInitLoopExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayInitLoopExprClass"); return ErrorUnexpected; - case clang::Stmt::ArrayTypeTraitExprClass: + case ZigClangStmt_ArrayTypeTraitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayTypeTraitExprClass"); return ErrorUnexpected; - case clang::Stmt::AsTypeExprClass: + case ZigClangStmt_AsTypeExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AsTypeExprClass"); return ErrorUnexpected; - case clang::Stmt::AtomicExprClass: + case ZigClangStmt_AtomicExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AtomicExprClass"); return ErrorUnexpected; - case clang::Stmt::BlockExprClass: + case ZigClangStmt_BlockExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BlockExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXBindTemporaryExprClass: + case ZigClangStmt_CXXBindTemporaryExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXBindTemporaryExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXBoolLiteralExprClass: + case ZigClangStmt_CXXBoolLiteralExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXBoolLiteralExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXConstructExprClass: + case ZigClangStmt_CXXConstructExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstructExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXTemporaryObjectExprClass: + case ZigClangStmt_CXXTemporaryObjectExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTemporaryObjectExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXDefaultArgExprClass: + case ZigClangStmt_CXXDefaultArgExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDefaultArgExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXDefaultInitExprClass: + case ZigClangStmt_CXXDefaultInitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDefaultInitExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXDeleteExprClass: + case ZigClangStmt_CXXDeleteExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDeleteExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXDependentScopeMemberExprClass: + case ZigClangStmt_CXXDependentScopeMemberExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDependentScopeMemberExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXFoldExprClass: + case ZigClangStmt_CXXFoldExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXFoldExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXInheritedCtorInitExprClass: + case ZigClangStmt_CXXInheritedCtorInitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXInheritedCtorInitExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXNewExprClass: + case ZigClangStmt_CXXNewExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNewExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXNoexceptExprClass: + case ZigClangStmt_CXXNoexceptExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNoexceptExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXNullPtrLiteralExprClass: + case ZigClangStmt_CXXNullPtrLiteralExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNullPtrLiteralExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXPseudoDestructorExprClass: + case ZigClangStmt_CXXPseudoDestructorExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXPseudoDestructorExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXScalarValueInitExprClass: + case ZigClangStmt_CXXScalarValueInitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXScalarValueInitExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXStdInitializerListExprClass: + case ZigClangStmt_CXXStdInitializerListExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXStdInitializerListExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXThisExprClass: + case ZigClangStmt_CXXThisExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXThisExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXThrowExprClass: + case ZigClangStmt_CXXThrowExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXThrowExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXTypeidExprClass: + case ZigClangStmt_CXXTypeidExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTypeidExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXUnresolvedConstructExprClass: + case ZigClangStmt_CXXUnresolvedConstructExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXUnresolvedConstructExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXUuidofExprClass: + case ZigClangStmt_CXXUuidofExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXUuidofExprClass"); return ErrorUnexpected; - case clang::Stmt::CUDAKernelCallExprClass: + case ZigClangStmt_CUDAKernelCallExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CUDAKernelCallExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXMemberCallExprClass: + case ZigClangStmt_CXXMemberCallExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXMemberCallExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXOperatorCallExprClass: + case ZigClangStmt_CXXOperatorCallExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXOperatorCallExprClass"); return ErrorUnexpected; - case clang::Stmt::UserDefinedLiteralClass: + case ZigClangStmt_UserDefinedLiteralClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UserDefinedLiteralClass"); return ErrorUnexpected; - case clang::Stmt::CXXFunctionalCastExprClass: + case ZigClangStmt_CXXFunctionalCastExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXFunctionalCastExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXConstCastExprClass: + case ZigClangStmt_CXXConstCastExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstCastExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXDynamicCastExprClass: + case ZigClangStmt_CXXDynamicCastExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDynamicCastExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXReinterpretCastExprClass: + case ZigClangStmt_CXXReinterpretCastExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXReinterpretCastExprClass"); return ErrorUnexpected; - case clang::Stmt::CXXStaticCastExprClass: + case ZigClangStmt_CXXStaticCastExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXStaticCastExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCBridgedCastExprClass: + case ZigClangStmt_ObjCBridgedCastExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBridgedCastExprClass"); return ErrorUnexpected; - case clang::Stmt::CharacterLiteralClass: + case ZigClangStmt_CharacterLiteralClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CharacterLiteralClass"); return ErrorUnexpected; - case clang::Stmt::ChooseExprClass: + case ZigClangStmt_ChooseExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ChooseExprClass"); return ErrorUnexpected; - case clang::Stmt::CompoundLiteralExprClass: + case ZigClangStmt_CompoundLiteralExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CompoundLiteralExprClass"); return ErrorUnexpected; - case clang::Stmt::ConvertVectorExprClass: + case ZigClangStmt_ConvertVectorExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ConvertVectorExprClass"); return ErrorUnexpected; - case clang::Stmt::CoawaitExprClass: + case ZigClangStmt_CoawaitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoawaitExprClass"); return ErrorUnexpected; - case clang::Stmt::CoyieldExprClass: + case ZigClangStmt_CoyieldExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoyieldExprClass"); return ErrorUnexpected; - case clang::Stmt::DependentCoawaitExprClass: + case ZigClangStmt_DependentCoawaitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DependentCoawaitExprClass"); return ErrorUnexpected; - case clang::Stmt::DependentScopeDeclRefExprClass: + case ZigClangStmt_DependentScopeDeclRefExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DependentScopeDeclRefExprClass"); return ErrorUnexpected; - case clang::Stmt::DesignatedInitExprClass: + case ZigClangStmt_DesignatedInitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DesignatedInitExprClass"); return ErrorUnexpected; - case clang::Stmt::DesignatedInitUpdateExprClass: + case ZigClangStmt_DesignatedInitUpdateExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DesignatedInitUpdateExprClass"); return ErrorUnexpected; - case clang::Stmt::ExpressionTraitExprClass: + case ZigClangStmt_ExpressionTraitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExpressionTraitExprClass"); return ErrorUnexpected; - case clang::Stmt::ExtVectorElementExprClass: + case ZigClangStmt_ExtVectorElementExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExtVectorElementExprClass"); return ErrorUnexpected; - case clang::Stmt::FixedPointLiteralClass: + case ZigClangStmt_FixedPointLiteralClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FixedPointLiteralClass"); return ErrorUnexpected; - case clang::Stmt::FloatingLiteralClass: + case ZigClangStmt_FloatingLiteralClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FloatingLiteralClass"); return ErrorUnexpected; - case clang::Stmt::ExprWithCleanupsClass: + case ZigClangStmt_ExprWithCleanupsClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExprWithCleanupsClass"); return ErrorUnexpected; - case clang::Stmt::FunctionParmPackExprClass: + case ZigClangStmt_FunctionParmPackExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FunctionParmPackExprClass"); return ErrorUnexpected; - case clang::Stmt::GNUNullExprClass: + case ZigClangStmt_GNUNullExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GNUNullExprClass"); return ErrorUnexpected; - case clang::Stmt::GenericSelectionExprClass: + case ZigClangStmt_GenericSelectionExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GenericSelectionExprClass"); return ErrorUnexpected; - case clang::Stmt::ImaginaryLiteralClass: + case ZigClangStmt_ImaginaryLiteralClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImaginaryLiteralClass"); return ErrorUnexpected; - case clang::Stmt::ImplicitValueInitExprClass: + case ZigClangStmt_ImplicitValueInitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImplicitValueInitExprClass"); return ErrorUnexpected; - case clang::Stmt::InitListExprClass: + case ZigClangStmt_InitListExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C InitListExprClass"); return ErrorUnexpected; - case clang::Stmt::LambdaExprClass: + case ZigClangStmt_LambdaExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LambdaExprClass"); return ErrorUnexpected; - case clang::Stmt::MSPropertyRefExprClass: + case ZigClangStmt_MSPropertyRefExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSPropertyRefExprClass"); return ErrorUnexpected; - case clang::Stmt::MSPropertySubscriptExprClass: + case ZigClangStmt_MSPropertySubscriptExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSPropertySubscriptExprClass"); return ErrorUnexpected; - case clang::Stmt::MaterializeTemporaryExprClass: + case ZigClangStmt_MaterializeTemporaryExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MaterializeTemporaryExprClass"); return ErrorUnexpected; - case clang::Stmt::NoInitExprClass: + case ZigClangStmt_NoInitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NoInitExprClass"); return ErrorUnexpected; - case clang::Stmt::OMPArraySectionExprClass: + case ZigClangStmt_OMPArraySectionExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPArraySectionExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCArrayLiteralClass: + case ZigClangStmt_ObjCArrayLiteralClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCArrayLiteralClass"); return ErrorUnexpected; - case clang::Stmt::ObjCAvailabilityCheckExprClass: + case ZigClangStmt_ObjCAvailabilityCheckExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAvailabilityCheckExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCBoolLiteralExprClass: + case ZigClangStmt_ObjCBoolLiteralExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBoolLiteralExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCBoxedExprClass: + case ZigClangStmt_ObjCBoxedExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBoxedExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCDictionaryLiteralClass: + case ZigClangStmt_ObjCDictionaryLiteralClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCDictionaryLiteralClass"); return ErrorUnexpected; - case clang::Stmt::ObjCEncodeExprClass: + case ZigClangStmt_ObjCEncodeExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCEncodeExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCIndirectCopyRestoreExprClass: + case ZigClangStmt_ObjCIndirectCopyRestoreExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIndirectCopyRestoreExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCIsaExprClass: + case ZigClangStmt_ObjCIsaExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIsaExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCIvarRefExprClass: + case ZigClangStmt_ObjCIvarRefExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIvarRefExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCMessageExprClass: + case ZigClangStmt_ObjCMessageExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCMessageExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCPropertyRefExprClass: + case ZigClangStmt_ObjCPropertyRefExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCPropertyRefExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCProtocolExprClass: + case ZigClangStmt_ObjCProtocolExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProtocolExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCSelectorExprClass: + case ZigClangStmt_ObjCSelectorExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCSelectorExprClass"); return ErrorUnexpected; - case clang::Stmt::ObjCStringLiteralClass: + case ZigClangStmt_ObjCStringLiteralClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCStringLiteralClass"); return ErrorUnexpected; - case clang::Stmt::ObjCSubscriptRefExprClass: + case ZigClangStmt_ObjCSubscriptRefExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCSubscriptRefExprClass"); return ErrorUnexpected; - case clang::Stmt::OffsetOfExprClass: + case ZigClangStmt_OffsetOfExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OffsetOfExprClass"); return ErrorUnexpected; - case clang::Stmt::OpaqueValueExprClass: + case ZigClangStmt_OpaqueValueExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OpaqueValueExprClass"); return ErrorUnexpected; - case clang::Stmt::UnresolvedLookupExprClass: + case ZigClangStmt_UnresolvedLookupExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedLookupExprClass"); return ErrorUnexpected; - case clang::Stmt::UnresolvedMemberExprClass: + case ZigClangStmt_UnresolvedMemberExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedMemberExprClass"); return ErrorUnexpected; - case clang::Stmt::PackExpansionExprClass: + case ZigClangStmt_PackExpansionExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PackExpansionExprClass"); return ErrorUnexpected; - case clang::Stmt::ParenListExprClass: + case ZigClangStmt_ParenListExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ParenListExprClass"); return ErrorUnexpected; - case clang::Stmt::PseudoObjectExprClass: + case ZigClangStmt_PseudoObjectExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PseudoObjectExprClass"); return ErrorUnexpected; - case clang::Stmt::ShuffleVectorExprClass: + case ZigClangStmt_ShuffleVectorExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ShuffleVectorExprClass"); return ErrorUnexpected; - case clang::Stmt::SizeOfPackExprClass: + case ZigClangStmt_SizeOfPackExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SizeOfPackExprClass"); return ErrorUnexpected; - case clang::Stmt::SubstNonTypeTemplateParmExprClass: + case ZigClangStmt_SubstNonTypeTemplateParmExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SubstNonTypeTemplateParmExprClass"); return ErrorUnexpected; - case clang::Stmt::SubstNonTypeTemplateParmPackExprClass: + case ZigClangStmt_SubstNonTypeTemplateParmPackExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SubstNonTypeTemplateParmPackExprClass"); return ErrorUnexpected; - case clang::Stmt::TypeTraitExprClass: + case ZigClangStmt_TypeTraitExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeTraitExprClass"); return ErrorUnexpected; - case clang::Stmt::TypoExprClass: + case ZigClangStmt_TypoExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypoExprClass"); return ErrorUnexpected; - case clang::Stmt::VAArgExprClass: + case ZigClangStmt_VAArgExprClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VAArgExprClass"); return ErrorUnexpected; - case clang::Stmt::GotoStmtClass: + case ZigClangStmt_GotoStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GotoStmtClass"); return ErrorUnexpected; - case clang::Stmt::IndirectGotoStmtClass: + case ZigClangStmt_IndirectGotoStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C IndirectGotoStmtClass"); return ErrorUnexpected; - case clang::Stmt::LabelStmtClass: + case ZigClangStmt_LabelStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LabelStmtClass"); return ErrorUnexpected; - case clang::Stmt::MSDependentExistsStmtClass: + case ZigClangStmt_MSDependentExistsStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSDependentExistsStmtClass"); return ErrorUnexpected; - case clang::Stmt::OMPAtomicDirectiveClass: + case ZigClangStmt_OMPAtomicDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPAtomicDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPBarrierDirectiveClass: + case ZigClangStmt_OMPBarrierDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPBarrierDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPCancelDirectiveClass: + case ZigClangStmt_OMPCancelDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCancelDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPCancellationPointDirectiveClass: + case ZigClangStmt_OMPCancellationPointDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCancellationPointDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPCriticalDirectiveClass: + case ZigClangStmt_OMPCriticalDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCriticalDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPFlushDirectiveClass: + case ZigClangStmt_OMPFlushDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPFlushDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPDistributeDirectiveClass: + case ZigClangStmt_OMPDistributeDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPDistributeParallelForDirectiveClass: + case ZigClangStmt_OMPDistributeParallelForDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeParallelForDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPDistributeParallelForSimdDirectiveClass: + case ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPDistributeSimdDirectiveClass: + case ZigClangStmt_OMPDistributeSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPForDirectiveClass: + case ZigClangStmt_OMPForDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPForDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPForSimdDirectiveClass: + case ZigClangStmt_OMPForSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPForSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPParallelForDirectiveClass: + case ZigClangStmt_OMPParallelForDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelForDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPParallelForSimdDirectiveClass: + case ZigClangStmt_OMPParallelForSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelForSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPSimdDirectiveClass: + case ZigClangStmt_OMPSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetParallelForSimdDirectiveClass: + case ZigClangStmt_OMPTargetParallelForSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelForSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetSimdDirectiveClass: + case ZigClangStmt_OMPTargetSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetTeamsDistributeDirectiveClass: + case ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: + case ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: + case ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: + case ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTaskLoopDirectiveClass: + case ZigClangStmt_OMPTaskLoopDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskLoopDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTaskLoopSimdDirectiveClass: + case ZigClangStmt_OMPTaskLoopSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskLoopSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTeamsDistributeDirectiveClass: + case ZigClangStmt_OMPTeamsDistributeDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass: + case ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: + case ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTeamsDistributeSimdDirectiveClass: + case ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeSimdDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPMasterDirectiveClass: + case ZigClangStmt_OMPMasterDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPMasterDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPOrderedDirectiveClass: + case ZigClangStmt_OMPOrderedDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPOrderedDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPParallelDirectiveClass: + case ZigClangStmt_OMPParallelDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPParallelSectionsDirectiveClass: + case ZigClangStmt_OMPParallelSectionsDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelSectionsDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPSectionDirectiveClass: + case ZigClangStmt_OMPSectionDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSectionDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPSectionsDirectiveClass: + case ZigClangStmt_OMPSectionsDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSectionsDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPSingleDirectiveClass: + case ZigClangStmt_OMPSingleDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSingleDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetDataDirectiveClass: + case ZigClangStmt_OMPTargetDataDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetDataDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetDirectiveClass: + case ZigClangStmt_OMPTargetDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetEnterDataDirectiveClass: + case ZigClangStmt_OMPTargetEnterDataDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetEnterDataDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetExitDataDirectiveClass: + case ZigClangStmt_OMPTargetExitDataDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetExitDataDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetParallelDirectiveClass: + case ZigClangStmt_OMPTargetParallelDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetParallelForDirectiveClass: + case ZigClangStmt_OMPTargetParallelForDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelForDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetTeamsDirectiveClass: + case ZigClangStmt_OMPTargetTeamsDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTargetUpdateDirectiveClass: + case ZigClangStmt_OMPTargetUpdateDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetUpdateDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTaskDirectiveClass: + case ZigClangStmt_OMPTaskDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTaskgroupDirectiveClass: + case ZigClangStmt_OMPTaskgroupDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskgroupDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTaskwaitDirectiveClass: + case ZigClangStmt_OMPTaskwaitDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskwaitDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTaskyieldDirectiveClass: + case ZigClangStmt_OMPTaskyieldDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskyieldDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::OMPTeamsDirectiveClass: + case ZigClangStmt_OMPTeamsDirectiveClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDirectiveClass"); return ErrorUnexpected; - case clang::Stmt::ObjCAtCatchStmtClass: + case ZigClangStmt_ObjCAtCatchStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtCatchStmtClass"); return ErrorUnexpected; - case clang::Stmt::ObjCAtFinallyStmtClass: + case ZigClangStmt_ObjCAtFinallyStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtFinallyStmtClass"); return ErrorUnexpected; - case clang::Stmt::ObjCAtSynchronizedStmtClass: + case ZigClangStmt_ObjCAtSynchronizedStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtSynchronizedStmtClass"); return ErrorUnexpected; - case clang::Stmt::ObjCAtThrowStmtClass: + case ZigClangStmt_ObjCAtThrowStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtThrowStmtClass"); return ErrorUnexpected; - case clang::Stmt::ObjCAtTryStmtClass: + case ZigClangStmt_ObjCAtTryStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtTryStmtClass"); return ErrorUnexpected; - case clang::Stmt::ObjCAutoreleasePoolStmtClass: + case ZigClangStmt_ObjCAutoreleasePoolStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAutoreleasePoolStmtClass"); return ErrorUnexpected; - case clang::Stmt::ObjCForCollectionStmtClass: + case ZigClangStmt_ObjCForCollectionStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCForCollectionStmtClass"); return ErrorUnexpected; - case clang::Stmt::SEHExceptStmtClass: + case ZigClangStmt_SEHExceptStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHExceptStmtClass"); return ErrorUnexpected; - case clang::Stmt::SEHFinallyStmtClass: + case ZigClangStmt_SEHFinallyStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHFinallyStmtClass"); return ErrorUnexpected; - case clang::Stmt::SEHLeaveStmtClass: + case ZigClangStmt_SEHLeaveStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHLeaveStmtClass"); return ErrorUnexpected; - case clang::Stmt::SEHTryStmtClass: + case ZigClangStmt_SEHTryStmtClass: emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHTryStmtClass"); return ErrorUnexpected; } diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 265a37d82a..c892426363 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -101,7 +101,7 @@ static_assert((clang::BinaryOperatorKind)ZigClangBO_SubAssign == clang::BO_SubAs static_assert((clang::BinaryOperatorKind)ZigClangBO_Xor == clang::BO_Xor, ""); static_assert((clang::BinaryOperatorKind)ZigClangBO_XorAssign == clang::BO_XorAssign, ""); -// This function detects additions to the enum +// Detect additions to the enum void zig2clang_UO(clang::UnaryOperatorKind op) { switch (op) { case clang::UO_AddrOf: @@ -137,6 +137,7 @@ static_assert((clang::UnaryOperatorKind)ZigClangUO_PreDec == clang::UO_PreDec, " static_assert((clang::UnaryOperatorKind)ZigClangUO_PreInc == clang::UO_PreInc, ""); static_assert((clang::UnaryOperatorKind)ZigClangUO_Real == clang::UO_Real, ""); +// Detect additions to the enum void zig2clang_TypeClass(clang::Type::TypeClass ty) { switch (ty) { case clang::Type::Builtin: @@ -238,6 +239,408 @@ static_assert((clang::Type::TypeClass)ZigClangType_ObjCObjectPointer == clang::T static_assert((clang::Type::TypeClass)ZigClangType_Pipe == clang::Type::Pipe, ""); static_assert((clang::Type::TypeClass)ZigClangType_Atomic == clang::Type::Atomic, ""); +// Detect additions to the enum +void zig2clang_StmtClass(clang::Stmt::StmtClass x) { + switch (x) { + case clang::Stmt::NoStmtClass: + case clang::Stmt::NullStmtClass: + case clang::Stmt::CompoundStmtClass: + case clang::Stmt::LabelStmtClass: + case clang::Stmt::AttributedStmtClass: + case clang::Stmt::IfStmtClass: + case clang::Stmt::SwitchStmtClass: + case clang::Stmt::WhileStmtClass: + case clang::Stmt::DoStmtClass: + case clang::Stmt::ForStmtClass: + case clang::Stmt::GotoStmtClass: + case clang::Stmt::IndirectGotoStmtClass: + case clang::Stmt::ContinueStmtClass: + case clang::Stmt::BreakStmtClass: + case clang::Stmt::ReturnStmtClass: + case clang::Stmt::DeclStmtClass: + case clang::Stmt::CaseStmtClass: + case clang::Stmt::DefaultStmtClass: + case clang::Stmt::CapturedStmtClass: + case clang::Stmt::GCCAsmStmtClass: + case clang::Stmt::MSAsmStmtClass: + case clang::Stmt::ObjCAtTryStmtClass: + case clang::Stmt::ObjCAtCatchStmtClass: + case clang::Stmt::ObjCAtFinallyStmtClass: + case clang::Stmt::ObjCAtThrowStmtClass: + case clang::Stmt::ObjCAtSynchronizedStmtClass: + case clang::Stmt::ObjCForCollectionStmtClass: + case clang::Stmt::ObjCAutoreleasePoolStmtClass: + case clang::Stmt::CXXCatchStmtClass: + case clang::Stmt::CXXTryStmtClass: + case clang::Stmt::CXXForRangeStmtClass: + case clang::Stmt::CoroutineBodyStmtClass: + case clang::Stmt::CoreturnStmtClass: + case clang::Stmt::PredefinedExprClass: + case clang::Stmt::DeclRefExprClass: + case clang::Stmt::IntegerLiteralClass: + case clang::Stmt::FixedPointLiteralClass: + case clang::Stmt::FloatingLiteralClass: + case clang::Stmt::ImaginaryLiteralClass: + case clang::Stmt::StringLiteralClass: + case clang::Stmt::CharacterLiteralClass: + case clang::Stmt::ParenExprClass: + case clang::Stmt::UnaryOperatorClass: + case clang::Stmt::OffsetOfExprClass: + case clang::Stmt::UnaryExprOrTypeTraitExprClass: + case clang::Stmt::ArraySubscriptExprClass: + case clang::Stmt::OMPArraySectionExprClass: + case clang::Stmt::CallExprClass: + case clang::Stmt::MemberExprClass: + case clang::Stmt::BinaryOperatorClass: + case clang::Stmt::CompoundAssignOperatorClass: + case clang::Stmt::ConditionalOperatorClass: + case clang::Stmt::BinaryConditionalOperatorClass: + case clang::Stmt::ImplicitCastExprClass: + case clang::Stmt::CStyleCastExprClass: + case clang::Stmt::CompoundLiteralExprClass: + case clang::Stmt::ExtVectorElementExprClass: + case clang::Stmt::InitListExprClass: + case clang::Stmt::DesignatedInitExprClass: + case clang::Stmt::DesignatedInitUpdateExprClass: + case clang::Stmt::ImplicitValueInitExprClass: + case clang::Stmt::NoInitExprClass: + case clang::Stmt::ArrayInitLoopExprClass: + case clang::Stmt::ArrayInitIndexExprClass: + case clang::Stmt::ParenListExprClass: + case clang::Stmt::VAArgExprClass: + case clang::Stmt::GenericSelectionExprClass: + case clang::Stmt::PseudoObjectExprClass: + case clang::Stmt::ConstantExprClass: + case clang::Stmt::AtomicExprClass: + case clang::Stmt::AddrLabelExprClass: + case clang::Stmt::StmtExprClass: + case clang::Stmt::ChooseExprClass: + case clang::Stmt::GNUNullExprClass: + case clang::Stmt::CXXOperatorCallExprClass: + case clang::Stmt::CXXMemberCallExprClass: + case clang::Stmt::CXXStaticCastExprClass: + case clang::Stmt::CXXDynamicCastExprClass: + case clang::Stmt::CXXReinterpretCastExprClass: + case clang::Stmt::CXXConstCastExprClass: + case clang::Stmt::CXXFunctionalCastExprClass: + case clang::Stmt::CXXTypeidExprClass: + case clang::Stmt::UserDefinedLiteralClass: + case clang::Stmt::CXXBoolLiteralExprClass: + case clang::Stmt::CXXNullPtrLiteralExprClass: + case clang::Stmt::CXXThisExprClass: + case clang::Stmt::CXXThrowExprClass: + case clang::Stmt::CXXDefaultArgExprClass: + case clang::Stmt::CXXDefaultInitExprClass: + case clang::Stmt::CXXScalarValueInitExprClass: + case clang::Stmt::CXXStdInitializerListExprClass: + case clang::Stmt::CXXNewExprClass: + case clang::Stmt::CXXDeleteExprClass: + case clang::Stmt::CXXPseudoDestructorExprClass: + case clang::Stmt::TypeTraitExprClass: + case clang::Stmt::ArrayTypeTraitExprClass: + case clang::Stmt::ExpressionTraitExprClass: + case clang::Stmt::DependentScopeDeclRefExprClass: + case clang::Stmt::CXXConstructExprClass: + case clang::Stmt::CXXInheritedCtorInitExprClass: + case clang::Stmt::CXXBindTemporaryExprClass: + case clang::Stmt::ExprWithCleanupsClass: + case clang::Stmt::CXXTemporaryObjectExprClass: + case clang::Stmt::CXXUnresolvedConstructExprClass: + case clang::Stmt::CXXDependentScopeMemberExprClass: + case clang::Stmt::UnresolvedLookupExprClass: + case clang::Stmt::UnresolvedMemberExprClass: + case clang::Stmt::CXXNoexceptExprClass: + case clang::Stmt::PackExpansionExprClass: + case clang::Stmt::SizeOfPackExprClass: + case clang::Stmt::SubstNonTypeTemplateParmExprClass: + case clang::Stmt::SubstNonTypeTemplateParmPackExprClass: + case clang::Stmt::FunctionParmPackExprClass: + case clang::Stmt::MaterializeTemporaryExprClass: + case clang::Stmt::LambdaExprClass: + case clang::Stmt::CXXFoldExprClass: + case clang::Stmt::CoawaitExprClass: + case clang::Stmt::DependentCoawaitExprClass: + case clang::Stmt::CoyieldExprClass: + case clang::Stmt::ObjCStringLiteralClass: + case clang::Stmt::ObjCBoxedExprClass: + case clang::Stmt::ObjCArrayLiteralClass: + case clang::Stmt::ObjCDictionaryLiteralClass: + case clang::Stmt::ObjCEncodeExprClass: + case clang::Stmt::ObjCMessageExprClass: + case clang::Stmt::ObjCSelectorExprClass: + case clang::Stmt::ObjCProtocolExprClass: + case clang::Stmt::ObjCIvarRefExprClass: + case clang::Stmt::ObjCPropertyRefExprClass: + case clang::Stmt::ObjCIsaExprClass: + case clang::Stmt::ObjCIndirectCopyRestoreExprClass: + case clang::Stmt::ObjCBoolLiteralExprClass: + case clang::Stmt::ObjCSubscriptRefExprClass: + case clang::Stmt::ObjCAvailabilityCheckExprClass: + case clang::Stmt::ObjCBridgedCastExprClass: + case clang::Stmt::CUDAKernelCallExprClass: + case clang::Stmt::ShuffleVectorExprClass: + case clang::Stmt::ConvertVectorExprClass: + case clang::Stmt::BlockExprClass: + case clang::Stmt::OpaqueValueExprClass: + case clang::Stmt::TypoExprClass: + case clang::Stmt::MSPropertyRefExprClass: + case clang::Stmt::MSPropertySubscriptExprClass: + case clang::Stmt::CXXUuidofExprClass: + case clang::Stmt::SEHTryStmtClass: + case clang::Stmt::SEHExceptStmtClass: + case clang::Stmt::SEHFinallyStmtClass: + case clang::Stmt::SEHLeaveStmtClass: + case clang::Stmt::MSDependentExistsStmtClass: + case clang::Stmt::AsTypeExprClass: + case clang::Stmt::OMPParallelDirectiveClass: + case clang::Stmt::OMPSimdDirectiveClass: + case clang::Stmt::OMPForDirectiveClass: + case clang::Stmt::OMPForSimdDirectiveClass: + case clang::Stmt::OMPSectionsDirectiveClass: + case clang::Stmt::OMPSectionDirectiveClass: + case clang::Stmt::OMPSingleDirectiveClass: + case clang::Stmt::OMPMasterDirectiveClass: + case clang::Stmt::OMPCriticalDirectiveClass: + case clang::Stmt::OMPParallelForDirectiveClass: + case clang::Stmt::OMPParallelForSimdDirectiveClass: + case clang::Stmt::OMPParallelSectionsDirectiveClass: + case clang::Stmt::OMPTaskDirectiveClass: + case clang::Stmt::OMPTaskyieldDirectiveClass: + case clang::Stmt::OMPBarrierDirectiveClass: + case clang::Stmt::OMPTaskwaitDirectiveClass: + case clang::Stmt::OMPTaskgroupDirectiveClass: + case clang::Stmt::OMPFlushDirectiveClass: + case clang::Stmt::OMPOrderedDirectiveClass: + case clang::Stmt::OMPAtomicDirectiveClass: + case clang::Stmt::OMPTargetDirectiveClass: + case clang::Stmt::OMPTargetDataDirectiveClass: + case clang::Stmt::OMPTargetEnterDataDirectiveClass: + case clang::Stmt::OMPTargetExitDataDirectiveClass: + case clang::Stmt::OMPTargetParallelDirectiveClass: + case clang::Stmt::OMPTargetParallelForDirectiveClass: + case clang::Stmt::OMPTargetUpdateDirectiveClass: + case clang::Stmt::OMPTeamsDirectiveClass: + case clang::Stmt::OMPCancellationPointDirectiveClass: + case clang::Stmt::OMPCancelDirectiveClass: + case clang::Stmt::OMPTaskLoopDirectiveClass: + case clang::Stmt::OMPTaskLoopSimdDirectiveClass: + case clang::Stmt::OMPDistributeDirectiveClass: + case clang::Stmt::OMPDistributeParallelForDirectiveClass: + case clang::Stmt::OMPDistributeParallelForSimdDirectiveClass: + case clang::Stmt::OMPDistributeSimdDirectiveClass: + case clang::Stmt::OMPTargetParallelForSimdDirectiveClass: + case clang::Stmt::OMPTargetSimdDirectiveClass: + case clang::Stmt::OMPTeamsDistributeDirectiveClass: + case clang::Stmt::OMPTeamsDistributeSimdDirectiveClass: + case clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: + case clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass: + case clang::Stmt::OMPTargetTeamsDirectiveClass: + case clang::Stmt::OMPTargetTeamsDistributeDirectiveClass: + case clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: + case clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: + case clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: + break; + } +} + +static_assert((clang::Stmt::StmtClass)ZigClangStmt_NoStmtClass == clang::Stmt::NoStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_NullStmtClass == clang::Stmt::NullStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CompoundStmtClass == clang::Stmt::CompoundStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_LabelStmtClass == clang::Stmt::LabelStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_AttributedStmtClass == clang::Stmt::AttributedStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_IfStmtClass == clang::Stmt::IfStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_SwitchStmtClass == clang::Stmt::SwitchStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_WhileStmtClass == clang::Stmt::WhileStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_DoStmtClass == clang::Stmt::DoStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ForStmtClass == clang::Stmt::ForStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_GotoStmtClass == clang::Stmt::GotoStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_IndirectGotoStmtClass == clang::Stmt::IndirectGotoStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ContinueStmtClass == clang::Stmt::ContinueStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_BreakStmtClass == clang::Stmt::BreakStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ReturnStmtClass == clang::Stmt::ReturnStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_DeclStmtClass == clang::Stmt::DeclStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CaseStmtClass == clang::Stmt::CaseStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_DefaultStmtClass == clang::Stmt::DefaultStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CapturedStmtClass == clang::Stmt::CapturedStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_GCCAsmStmtClass == clang::Stmt::GCCAsmStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_MSAsmStmtClass == clang::Stmt::MSAsmStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtTryStmtClass == clang::Stmt::ObjCAtTryStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtCatchStmtClass == clang::Stmt::ObjCAtCatchStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtFinallyStmtClass == clang::Stmt::ObjCAtFinallyStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtThrowStmtClass == clang::Stmt::ObjCAtThrowStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtSynchronizedStmtClass == clang::Stmt::ObjCAtSynchronizedStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCForCollectionStmtClass == clang::Stmt::ObjCForCollectionStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAutoreleasePoolStmtClass == clang::Stmt::ObjCAutoreleasePoolStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXCatchStmtClass == clang::Stmt::CXXCatchStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXTryStmtClass == clang::Stmt::CXXTryStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXForRangeStmtClass == clang::Stmt::CXXForRangeStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CoroutineBodyStmtClass == clang::Stmt::CoroutineBodyStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CoreturnStmtClass == clang::Stmt::CoreturnStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_PredefinedExprClass == clang::Stmt::PredefinedExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_DeclRefExprClass == clang::Stmt::DeclRefExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_IntegerLiteralClass == clang::Stmt::IntegerLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_FixedPointLiteralClass == clang::Stmt::FixedPointLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_FloatingLiteralClass == clang::Stmt::FloatingLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ImaginaryLiteralClass == clang::Stmt::ImaginaryLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_StringLiteralClass == clang::Stmt::StringLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CharacterLiteralClass == clang::Stmt::CharacterLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ParenExprClass == clang::Stmt::ParenExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_UnaryOperatorClass == clang::Stmt::UnaryOperatorClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OffsetOfExprClass == clang::Stmt::OffsetOfExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_UnaryExprOrTypeTraitExprClass == clang::Stmt::UnaryExprOrTypeTraitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ArraySubscriptExprClass == clang::Stmt::ArraySubscriptExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPArraySectionExprClass == clang::Stmt::OMPArraySectionExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CallExprClass == clang::Stmt::CallExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_MemberExprClass == clang::Stmt::MemberExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_BinaryOperatorClass == clang::Stmt::BinaryOperatorClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CompoundAssignOperatorClass == clang::Stmt::CompoundAssignOperatorClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ConditionalOperatorClass == clang::Stmt::ConditionalOperatorClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_BinaryConditionalOperatorClass == clang::Stmt::BinaryConditionalOperatorClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ImplicitCastExprClass == clang::Stmt::ImplicitCastExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CStyleCastExprClass == clang::Stmt::CStyleCastExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CompoundLiteralExprClass == clang::Stmt::CompoundLiteralExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ExtVectorElementExprClass == clang::Stmt::ExtVectorElementExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_InitListExprClass == clang::Stmt::InitListExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_DesignatedInitExprClass == clang::Stmt::DesignatedInitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_DesignatedInitUpdateExprClass == clang::Stmt::DesignatedInitUpdateExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ImplicitValueInitExprClass == clang::Stmt::ImplicitValueInitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_NoInitExprClass == clang::Stmt::NoInitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ArrayInitLoopExprClass == clang::Stmt::ArrayInitLoopExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ArrayInitIndexExprClass == clang::Stmt::ArrayInitIndexExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ParenListExprClass == clang::Stmt::ParenListExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_VAArgExprClass == clang::Stmt::VAArgExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_GenericSelectionExprClass == clang::Stmt::GenericSelectionExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_PseudoObjectExprClass == clang::Stmt::PseudoObjectExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ConstantExprClass == clang::Stmt::ConstantExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_AtomicExprClass == clang::Stmt::AtomicExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_AddrLabelExprClass == clang::Stmt::AddrLabelExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_StmtExprClass == clang::Stmt::StmtExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ChooseExprClass == clang::Stmt::ChooseExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_GNUNullExprClass == clang::Stmt::GNUNullExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXOperatorCallExprClass == clang::Stmt::CXXOperatorCallExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXMemberCallExprClass == clang::Stmt::CXXMemberCallExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXStaticCastExprClass == clang::Stmt::CXXStaticCastExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDynamicCastExprClass == clang::Stmt::CXXDynamicCastExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXReinterpretCastExprClass == clang::Stmt::CXXReinterpretCastExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXConstCastExprClass == clang::Stmt::CXXConstCastExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXFunctionalCastExprClass == clang::Stmt::CXXFunctionalCastExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXTypeidExprClass == clang::Stmt::CXXTypeidExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_UserDefinedLiteralClass == clang::Stmt::UserDefinedLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXBoolLiteralExprClass == clang::Stmt::CXXBoolLiteralExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXNullPtrLiteralExprClass == clang::Stmt::CXXNullPtrLiteralExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXThisExprClass == clang::Stmt::CXXThisExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXThrowExprClass == clang::Stmt::CXXThrowExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDefaultArgExprClass == clang::Stmt::CXXDefaultArgExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDefaultInitExprClass == clang::Stmt::CXXDefaultInitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXScalarValueInitExprClass == clang::Stmt::CXXScalarValueInitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXStdInitializerListExprClass == clang::Stmt::CXXStdInitializerListExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXNewExprClass == clang::Stmt::CXXNewExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDeleteExprClass == clang::Stmt::CXXDeleteExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXPseudoDestructorExprClass == clang::Stmt::CXXPseudoDestructorExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_TypeTraitExprClass == clang::Stmt::TypeTraitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ArrayTypeTraitExprClass == clang::Stmt::ArrayTypeTraitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ExpressionTraitExprClass == clang::Stmt::ExpressionTraitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_DependentScopeDeclRefExprClass == clang::Stmt::DependentScopeDeclRefExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXConstructExprClass == clang::Stmt::CXXConstructExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXInheritedCtorInitExprClass == clang::Stmt::CXXInheritedCtorInitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXBindTemporaryExprClass == clang::Stmt::CXXBindTemporaryExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ExprWithCleanupsClass == clang::Stmt::ExprWithCleanupsClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXTemporaryObjectExprClass == clang::Stmt::CXXTemporaryObjectExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXUnresolvedConstructExprClass == clang::Stmt::CXXUnresolvedConstructExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDependentScopeMemberExprClass == clang::Stmt::CXXDependentScopeMemberExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_UnresolvedLookupExprClass == clang::Stmt::UnresolvedLookupExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_UnresolvedMemberExprClass == clang::Stmt::UnresolvedMemberExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXNoexceptExprClass == clang::Stmt::CXXNoexceptExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_PackExpansionExprClass == clang::Stmt::PackExpansionExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_SizeOfPackExprClass == clang::Stmt::SizeOfPackExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_SubstNonTypeTemplateParmExprClass == clang::Stmt::SubstNonTypeTemplateParmExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_SubstNonTypeTemplateParmPackExprClass == clang::Stmt::SubstNonTypeTemplateParmPackExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_FunctionParmPackExprClass == clang::Stmt::FunctionParmPackExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_MaterializeTemporaryExprClass == clang::Stmt::MaterializeTemporaryExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_LambdaExprClass == clang::Stmt::LambdaExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXFoldExprClass == clang::Stmt::CXXFoldExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CoawaitExprClass == clang::Stmt::CoawaitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_DependentCoawaitExprClass == clang::Stmt::DependentCoawaitExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CoyieldExprClass == clang::Stmt::CoyieldExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCStringLiteralClass == clang::Stmt::ObjCStringLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCBoxedExprClass == clang::Stmt::ObjCBoxedExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCArrayLiteralClass == clang::Stmt::ObjCArrayLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCDictionaryLiteralClass == clang::Stmt::ObjCDictionaryLiteralClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCEncodeExprClass == clang::Stmt::ObjCEncodeExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCMessageExprClass == clang::Stmt::ObjCMessageExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCSelectorExprClass == clang::Stmt::ObjCSelectorExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCProtocolExprClass == clang::Stmt::ObjCProtocolExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCIvarRefExprClass == clang::Stmt::ObjCIvarRefExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCPropertyRefExprClass == clang::Stmt::ObjCPropertyRefExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCIsaExprClass == clang::Stmt::ObjCIsaExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCIndirectCopyRestoreExprClass == clang::Stmt::ObjCIndirectCopyRestoreExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCBoolLiteralExprClass == clang::Stmt::ObjCBoolLiteralExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCSubscriptRefExprClass == clang::Stmt::ObjCSubscriptRefExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAvailabilityCheckExprClass == clang::Stmt::ObjCAvailabilityCheckExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCBridgedCastExprClass == clang::Stmt::ObjCBridgedCastExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CUDAKernelCallExprClass == clang::Stmt::CUDAKernelCallExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ShuffleVectorExprClass == clang::Stmt::ShuffleVectorExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_ConvertVectorExprClass == clang::Stmt::ConvertVectorExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_BlockExprClass == clang::Stmt::BlockExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OpaqueValueExprClass == clang::Stmt::OpaqueValueExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_TypoExprClass == clang::Stmt::TypoExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_MSPropertyRefExprClass == clang::Stmt::MSPropertyRefExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_MSPropertySubscriptExprClass == clang::Stmt::MSPropertySubscriptExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXUuidofExprClass == clang::Stmt::CXXUuidofExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_SEHTryStmtClass == clang::Stmt::SEHTryStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_SEHExceptStmtClass == clang::Stmt::SEHExceptStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_SEHFinallyStmtClass == clang::Stmt::SEHFinallyStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_SEHLeaveStmtClass == clang::Stmt::SEHLeaveStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_MSDependentExistsStmtClass == clang::Stmt::MSDependentExistsStmtClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_AsTypeExprClass == clang::Stmt::AsTypeExprClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelDirectiveClass == clang::Stmt::OMPParallelDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSimdDirectiveClass == clang::Stmt::OMPSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPForDirectiveClass == clang::Stmt::OMPForDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPForSimdDirectiveClass == clang::Stmt::OMPForSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSectionsDirectiveClass == clang::Stmt::OMPSectionsDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSectionDirectiveClass == clang::Stmt::OMPSectionDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSingleDirectiveClass == clang::Stmt::OMPSingleDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMasterDirectiveClass == clang::Stmt::OMPMasterDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPCriticalDirectiveClass == clang::Stmt::OMPCriticalDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelForDirectiveClass == clang::Stmt::OMPParallelForDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelForSimdDirectiveClass == clang::Stmt::OMPParallelForSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelSectionsDirectiveClass == clang::Stmt::OMPParallelSectionsDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskDirectiveClass == clang::Stmt::OMPTaskDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskyieldDirectiveClass == clang::Stmt::OMPTaskyieldDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPBarrierDirectiveClass == clang::Stmt::OMPBarrierDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskwaitDirectiveClass == clang::Stmt::OMPTaskwaitDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskgroupDirectiveClass == clang::Stmt::OMPTaskgroupDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPFlushDirectiveClass == clang::Stmt::OMPFlushDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPOrderedDirectiveClass == clang::Stmt::OMPOrderedDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPAtomicDirectiveClass == clang::Stmt::OMPAtomicDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetDirectiveClass == clang::Stmt::OMPTargetDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetDataDirectiveClass == clang::Stmt::OMPTargetDataDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetEnterDataDirectiveClass == clang::Stmt::OMPTargetEnterDataDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetExitDataDirectiveClass == clang::Stmt::OMPTargetExitDataDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetParallelDirectiveClass == clang::Stmt::OMPTargetParallelDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetParallelForDirectiveClass == clang::Stmt::OMPTargetParallelForDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetUpdateDirectiveClass == clang::Stmt::OMPTargetUpdateDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDirectiveClass == clang::Stmt::OMPTeamsDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPCancellationPointDirectiveClass == clang::Stmt::OMPCancellationPointDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPCancelDirectiveClass == clang::Stmt::OMPCancelDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskLoopDirectiveClass == clang::Stmt::OMPTaskLoopDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskLoopSimdDirectiveClass == clang::Stmt::OMPTaskLoopSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeDirectiveClass == clang::Stmt::OMPDistributeDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeParallelForDirectiveClass == clang::Stmt::OMPDistributeParallelForDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass == clang::Stmt::OMPDistributeParallelForSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeSimdDirectiveClass == clang::Stmt::OMPDistributeSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetParallelForSimdDirectiveClass == clang::Stmt::OMPTargetParallelForSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetSimdDirectiveClass == clang::Stmt::OMPTargetSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeDirectiveClass == clang::Stmt::OMPTeamsDistributeDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass == clang::Stmt::OMPTeamsDistributeSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass == clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass == clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDirectiveClass == clang::Stmt::OMPTargetTeamsDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass, ""); +static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass, ""); + static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), ""); static ZigClangSourceLocation bitcast(clang::SourceLocation src) { diff --git a/src/zig_clang.h b/src/zig_clang.h index 1e96e9a8e7..6f3f14a4e1 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -200,6 +200,206 @@ enum ZigClangTypeClass { ZigClangType_Atomic, }; +enum ZigClangStmtClass { + ZigClangStmt_NoStmtClass = 0, + ZigClangStmt_GCCAsmStmtClass, + ZigClangStmt_MSAsmStmtClass, + ZigClangStmt_AttributedStmtClass, + ZigClangStmt_BreakStmtClass, + ZigClangStmt_CXXCatchStmtClass, + ZigClangStmt_CXXForRangeStmtClass, + ZigClangStmt_CXXTryStmtClass, + ZigClangStmt_CapturedStmtClass, + ZigClangStmt_CompoundStmtClass, + ZigClangStmt_ContinueStmtClass, + ZigClangStmt_CoreturnStmtClass, + ZigClangStmt_CoroutineBodyStmtClass, + ZigClangStmt_DeclStmtClass, + ZigClangStmt_DoStmtClass, + ZigClangStmt_BinaryConditionalOperatorClass, + ZigClangStmt_ConditionalOperatorClass, + ZigClangStmt_AddrLabelExprClass, + ZigClangStmt_ArrayInitIndexExprClass, + ZigClangStmt_ArrayInitLoopExprClass, + ZigClangStmt_ArraySubscriptExprClass, + ZigClangStmt_ArrayTypeTraitExprClass, + ZigClangStmt_AsTypeExprClass, + ZigClangStmt_AtomicExprClass, + ZigClangStmt_BinaryOperatorClass, + ZigClangStmt_CompoundAssignOperatorClass, + ZigClangStmt_BlockExprClass, + ZigClangStmt_CXXBindTemporaryExprClass, + ZigClangStmt_CXXBoolLiteralExprClass, + ZigClangStmt_CXXConstructExprClass, + ZigClangStmt_CXXTemporaryObjectExprClass, + ZigClangStmt_CXXDefaultArgExprClass, + ZigClangStmt_CXXDefaultInitExprClass, + ZigClangStmt_CXXDeleteExprClass, + ZigClangStmt_CXXDependentScopeMemberExprClass, + ZigClangStmt_CXXFoldExprClass, + ZigClangStmt_CXXInheritedCtorInitExprClass, + ZigClangStmt_CXXNewExprClass, + ZigClangStmt_CXXNoexceptExprClass, + ZigClangStmt_CXXNullPtrLiteralExprClass, + ZigClangStmt_CXXPseudoDestructorExprClass, + ZigClangStmt_CXXScalarValueInitExprClass, + ZigClangStmt_CXXStdInitializerListExprClass, + ZigClangStmt_CXXThisExprClass, + ZigClangStmt_CXXThrowExprClass, + ZigClangStmt_CXXTypeidExprClass, + ZigClangStmt_CXXUnresolvedConstructExprClass, + ZigClangStmt_CXXUuidofExprClass, + ZigClangStmt_CallExprClass, + ZigClangStmt_CUDAKernelCallExprClass, + ZigClangStmt_CXXMemberCallExprClass, + ZigClangStmt_CXXOperatorCallExprClass, + ZigClangStmt_UserDefinedLiteralClass, + ZigClangStmt_CStyleCastExprClass, + ZigClangStmt_CXXFunctionalCastExprClass, + ZigClangStmt_CXXConstCastExprClass, + ZigClangStmt_CXXDynamicCastExprClass, + ZigClangStmt_CXXReinterpretCastExprClass, + ZigClangStmt_CXXStaticCastExprClass, + ZigClangStmt_ObjCBridgedCastExprClass, + ZigClangStmt_ImplicitCastExprClass, + ZigClangStmt_CharacterLiteralClass, + ZigClangStmt_ChooseExprClass, + ZigClangStmt_CompoundLiteralExprClass, + ZigClangStmt_ConvertVectorExprClass, + ZigClangStmt_CoawaitExprClass, + ZigClangStmt_CoyieldExprClass, + ZigClangStmt_DeclRefExprClass, + ZigClangStmt_DependentCoawaitExprClass, + ZigClangStmt_DependentScopeDeclRefExprClass, + ZigClangStmt_DesignatedInitExprClass, + ZigClangStmt_DesignatedInitUpdateExprClass, + ZigClangStmt_ExpressionTraitExprClass, + ZigClangStmt_ExtVectorElementExprClass, + ZigClangStmt_FixedPointLiteralClass, + ZigClangStmt_FloatingLiteralClass, + ZigClangStmt_ConstantExprClass, + ZigClangStmt_ExprWithCleanupsClass, + ZigClangStmt_FunctionParmPackExprClass, + ZigClangStmt_GNUNullExprClass, + ZigClangStmt_GenericSelectionExprClass, + ZigClangStmt_ImaginaryLiteralClass, + ZigClangStmt_ImplicitValueInitExprClass, + ZigClangStmt_InitListExprClass, + ZigClangStmt_IntegerLiteralClass, + ZigClangStmt_LambdaExprClass, + ZigClangStmt_MSPropertyRefExprClass, + ZigClangStmt_MSPropertySubscriptExprClass, + ZigClangStmt_MaterializeTemporaryExprClass, + ZigClangStmt_MemberExprClass, + ZigClangStmt_NoInitExprClass, + ZigClangStmt_OMPArraySectionExprClass, + ZigClangStmt_ObjCArrayLiteralClass, + ZigClangStmt_ObjCAvailabilityCheckExprClass, + ZigClangStmt_ObjCBoolLiteralExprClass, + ZigClangStmt_ObjCBoxedExprClass, + ZigClangStmt_ObjCDictionaryLiteralClass, + ZigClangStmt_ObjCEncodeExprClass, + ZigClangStmt_ObjCIndirectCopyRestoreExprClass, + ZigClangStmt_ObjCIsaExprClass, + ZigClangStmt_ObjCIvarRefExprClass, + ZigClangStmt_ObjCMessageExprClass, + ZigClangStmt_ObjCPropertyRefExprClass, + ZigClangStmt_ObjCProtocolExprClass, + ZigClangStmt_ObjCSelectorExprClass, + ZigClangStmt_ObjCStringLiteralClass, + ZigClangStmt_ObjCSubscriptRefExprClass, + ZigClangStmt_OffsetOfExprClass, + ZigClangStmt_OpaqueValueExprClass, + ZigClangStmt_UnresolvedLookupExprClass, + ZigClangStmt_UnresolvedMemberExprClass, + ZigClangStmt_PackExpansionExprClass, + ZigClangStmt_ParenExprClass, + ZigClangStmt_ParenListExprClass, + ZigClangStmt_PredefinedExprClass, + ZigClangStmt_PseudoObjectExprClass, + ZigClangStmt_ShuffleVectorExprClass, + ZigClangStmt_SizeOfPackExprClass, + ZigClangStmt_StmtExprClass, + ZigClangStmt_StringLiteralClass, + ZigClangStmt_SubstNonTypeTemplateParmExprClass, + ZigClangStmt_SubstNonTypeTemplateParmPackExprClass, + ZigClangStmt_TypeTraitExprClass, + ZigClangStmt_TypoExprClass, + ZigClangStmt_UnaryExprOrTypeTraitExprClass, + ZigClangStmt_UnaryOperatorClass, + ZigClangStmt_VAArgExprClass, + ZigClangStmt_ForStmtClass, + ZigClangStmt_GotoStmtClass, + ZigClangStmt_IfStmtClass, + ZigClangStmt_IndirectGotoStmtClass, + ZigClangStmt_LabelStmtClass, + ZigClangStmt_MSDependentExistsStmtClass, + ZigClangStmt_NullStmtClass, + ZigClangStmt_OMPAtomicDirectiveClass, + ZigClangStmt_OMPBarrierDirectiveClass, + ZigClangStmt_OMPCancelDirectiveClass, + ZigClangStmt_OMPCancellationPointDirectiveClass, + ZigClangStmt_OMPCriticalDirectiveClass, + ZigClangStmt_OMPFlushDirectiveClass, + ZigClangStmt_OMPDistributeDirectiveClass, + ZigClangStmt_OMPDistributeParallelForDirectiveClass, + ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass, + ZigClangStmt_OMPDistributeSimdDirectiveClass, + ZigClangStmt_OMPForDirectiveClass, + ZigClangStmt_OMPForSimdDirectiveClass, + ZigClangStmt_OMPParallelForDirectiveClass, + ZigClangStmt_OMPParallelForSimdDirectiveClass, + ZigClangStmt_OMPSimdDirectiveClass, + ZigClangStmt_OMPTargetParallelForSimdDirectiveClass, + ZigClangStmt_OMPTargetSimdDirectiveClass, + ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass, + ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass, + ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass, + ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass, + ZigClangStmt_OMPTaskLoopDirectiveClass, + ZigClangStmt_OMPTaskLoopSimdDirectiveClass, + ZigClangStmt_OMPTeamsDistributeDirectiveClass, + ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass, + ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass, + ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass, + ZigClangStmt_OMPMasterDirectiveClass, + ZigClangStmt_OMPOrderedDirectiveClass, + ZigClangStmt_OMPParallelDirectiveClass, + ZigClangStmt_OMPParallelSectionsDirectiveClass, + ZigClangStmt_OMPSectionDirectiveClass, + ZigClangStmt_OMPSectionsDirectiveClass, + ZigClangStmt_OMPSingleDirectiveClass, + ZigClangStmt_OMPTargetDataDirectiveClass, + ZigClangStmt_OMPTargetDirectiveClass, + ZigClangStmt_OMPTargetEnterDataDirectiveClass, + ZigClangStmt_OMPTargetExitDataDirectiveClass, + ZigClangStmt_OMPTargetParallelDirectiveClass, + ZigClangStmt_OMPTargetParallelForDirectiveClass, + ZigClangStmt_OMPTargetTeamsDirectiveClass, + ZigClangStmt_OMPTargetUpdateDirectiveClass, + ZigClangStmt_OMPTaskDirectiveClass, + ZigClangStmt_OMPTaskgroupDirectiveClass, + ZigClangStmt_OMPTaskwaitDirectiveClass, + ZigClangStmt_OMPTaskyieldDirectiveClass, + ZigClangStmt_OMPTeamsDirectiveClass, + ZigClangStmt_ObjCAtCatchStmtClass, + ZigClangStmt_ObjCAtFinallyStmtClass, + ZigClangStmt_ObjCAtSynchronizedStmtClass, + ZigClangStmt_ObjCAtThrowStmtClass, + ZigClangStmt_ObjCAtTryStmtClass, + ZigClangStmt_ObjCAutoreleasePoolStmtClass, + ZigClangStmt_ObjCForCollectionStmtClass, + ZigClangStmt_ReturnStmtClass, + ZigClangStmt_SEHExceptStmtClass, + ZigClangStmt_SEHFinallyStmtClass, + ZigClangStmt_SEHLeaveStmtClass, + ZigClangStmt_SEHTryStmtClass, + ZigClangStmt_CaseStmtClass, + ZigClangStmt_DefaultStmtClass, + ZigClangStmt_SwitchStmtClass, + ZigClangStmt_WhileStmtClass, +}; + //struct ZigClangCC_AAPCS; //struct ZigClangCC_AAPCS_VFP; //struct ZigClangCC_C; From 63f2e96eeaaa032ffa9ff11a4a632d8032883233 Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Fri, 12 Apr 2019 10:54:15 -0500 Subject: [PATCH 042/285] 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(-) 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); From 9d229791c68827f8890f0715dc05e3380693645d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 12 Apr 2019 14:38:15 -0400 Subject: [PATCH 043/285] translate-c: move some code to the C API See #1964 --- src/translate_c.cpp | 390 ++++++++++++++++++++++---------------------- src/zig_clang.cpp | 14 ++ src/zig_clang.h | 5 + 3 files changed, 217 insertions(+), 192 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 006b4e330f..f2e6f7fac6 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -116,16 +116,20 @@ static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl); static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl); -static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *stmt, +static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *stmt, ResultUsed result_used, TransLRValue lrval, AstNode **out_node, TransScope **out_child_scope, TransScope **out_node_scope); -static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node); +static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node); static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval); static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc); static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval); static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, ZigClangQualType qt, ZigClangSourceLocation source_loc); +static const ZigClangStmt *bitcast(const clang::Stmt *src) { + return reinterpret_cast(src); +} + static ZigClangSourceLocation bitcast(clang::SourceLocation src) { ZigClangSourceLocation dest; memcpy(&dest, static_cast(&src), sizeof(ZigClangSourceLocation)); @@ -1217,9 +1221,11 @@ static int trans_compound_stmt_inline(Context *c, TransScope *scope, const clang AstNode *block_node, TransScope **out_node_scope) { assert(block_node->type == NodeTypeBlock); - for (clang::CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) { + for (clang::CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); + it != end_it; ++it) + { AstNode *child_node; - scope = trans_stmt(c, scope, *it, &child_node); + scope = trans_stmt(c, scope, bitcast(*it), &child_node); if (scope == nullptr) return ErrorUnexpected; if (child_node != nullptr) @@ -2750,7 +2756,7 @@ static AstNode *trans_while_loop(Context *c, TransScope *scope, const clang::Whi if (while_scope->node->data.while_expr.condition == nullptr) return nullptr; - TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(), + TransScope *body_scope = trans_stmt(c, &while_scope->base, bitcast(stmt->getBody()), &while_scope->node->data.while_expr.body); if (body_scope == nullptr) return nullptr; @@ -2763,12 +2769,12 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const clang::I // if (c) t else e AstNode *if_node = trans_create_node(c, NodeTypeIfBoolExpr); - TransScope *then_scope = trans_stmt(c, scope, stmt->getThen(), &if_node->data.if_bool_expr.then_block); + TransScope *then_scope = trans_stmt(c, scope, bitcast(stmt->getThen()), &if_node->data.if_bool_expr.then_block); if (then_scope == nullptr) return nullptr; if (stmt->getElse() != nullptr) { - TransScope *else_scope = trans_stmt(c, scope, stmt->getElse(), &if_node->data.if_bool_expr.else_node); + TransScope *else_scope = trans_stmt(c, scope, bitcast(stmt->getElse()), &if_node->data.if_bool_expr.else_node); if (else_scope == nullptr) return nullptr; } @@ -2911,7 +2917,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang: // zig: } // We call the low level function so that we can set child_scope to the scope of the generated block. - if (trans_stmt_extra(c, &while_scope->base, stmt->getBody(), ResultUsedNo, TransRValue, &body_node, + if (trans_stmt_extra(c, &while_scope->base, bitcast(stmt->getBody()), ResultUsedNo, TransRValue, &body_node, nullptr, &child_scope)) { return nullptr; @@ -2929,7 +2935,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang: TransScopeBlock *child_block_scope = trans_scope_block_create(c, &while_scope->base); body_node = child_block_scope->node; AstNode *child_statement; - child_scope = trans_stmt(c, &child_block_scope->base, stmt->getBody(), &child_statement); + child_scope = trans_stmt(c, &child_block_scope->base, bitcast(stmt->getBody()), &child_statement); if (child_scope == nullptr) return nullptr; if (child_statement != nullptr) { body_node->data.block.statements.append(child_statement); @@ -2955,7 +2961,7 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const clang AstNode *loop_block_node; TransScopeWhile *while_scope; TransScope *cond_scope; - const clang::Stmt *init_stmt = stmt->getInit(); + const ZigClangStmt *init_stmt = bitcast(stmt->getInit()); if (init_stmt == nullptr) { while_scope = trans_scope_while_create(c, parent_scope); loop_block_node = while_scope->node; @@ -2976,12 +2982,12 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const clang child_scope->node->data.block.statements.append(while_scope->node); } - const clang::Stmt *cond_stmt = stmt->getCond(); + const ZigClangStmt *cond_stmt = bitcast(stmt->getCond()); if (cond_stmt == nullptr) { while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true); } else { - if (clang::Expr::classof(cond_stmt)) { - const clang::Expr *cond_expr = static_cast(cond_stmt); + if (ZigClangStmt_classof_Expr(cond_stmt)) { + const clang::Expr *cond_expr = reinterpret_cast(cond_stmt); while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope, cond_expr, TransRValue); if (while_scope->node->data.while_expr.condition == nullptr) @@ -2994,7 +3000,7 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const clang } } - const clang::Stmt *inc_stmt = stmt->getInc(); + const ZigClangStmt *inc_stmt = bitcast(stmt->getInc()); if (inc_stmt != nullptr) { AstNode *inc_node; TransScope *inc_scope = trans_stmt(c, cond_scope, inc_stmt, &inc_node); @@ -3004,7 +3010,7 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const clang } AstNode *body_statement; - TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(), &body_statement); + TransScope *body_scope = trans_stmt(c, &while_scope->base, bitcast(stmt->getBody()), &body_statement); if (body_scope == nullptr) return nullptr; @@ -3027,7 +3033,7 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const cl switch_scope = trans_scope_switch_create(c, &block_scope->base); } else { AstNode *vars_node; - TransScope *var_scope = trans_stmt(c, &block_scope->base, var_decl_stmt, &vars_node); + TransScope *var_scope = trans_stmt(c, &block_scope->base, (const ZigClangStmt *)var_decl_stmt, &vars_node); if (var_scope == nullptr) return nullptr; if (vars_node != nullptr) @@ -3050,8 +3056,8 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const cl switch_scope->switch_node->data.switch_expr.expr = expr_node; AstNode *body_node; - const clang::Stmt *body_stmt = stmt->getBody(); - if ((ZigClangStmtClass)body_stmt->getStmtClass() == ZigClangStmt_CompoundStmtClass) { + const ZigClangStmt *body_stmt = bitcast(stmt->getBody()); + if (ZigClangStmt_getStmtClass(body_stmt) == ZigClangStmt_CompoundStmtClass) { if (trans_compound_stmt_inline(c, &switch_scope->base, (const clang::CompoundStmt *)body_stmt, block_scope->node, nullptr)) { @@ -3119,7 +3125,7 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const clang:: scope_block->node->data.block.statements.append(case_block); AstNode *sub_stmt_node; - TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node); + TransScope *new_scope = trans_stmt(c, parent_scope, bitcast(stmt->getSubStmt()), &sub_stmt_node); if (new_scope == nullptr) return ErrorUnexpected; if (sub_stmt_node != nullptr) @@ -3156,7 +3162,7 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const clan scope_block->node->data.block.statements.append(case_block); AstNode *sub_stmt_node; - TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node); + TransScope *new_scope = trans_stmt(c, parent_scope, bitcast(stmt->getSubStmt()), &sub_stmt_node); if (new_scope == nullptr) return ErrorUnexpected; if (sub_stmt_node != nullptr) @@ -3219,12 +3225,12 @@ static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_ return ErrorNone; } -static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *stmt, +static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *stmt, ResultUsed result_used, TransLRValue lrvalue, AstNode **out_node, TransScope **out_child_scope, TransScope **out_node_scope) { - ZigClangStmtClass sc = (ZigClangStmtClass)stmt->getStmtClass(); + ZigClangStmtClass sc = ZigClangStmt_getStmtClass(stmt); switch (sc) { case ZigClangStmt_ReturnStmtClass: return wrap_stmt(out_node, out_child_scope, scope, @@ -3325,505 +3331,505 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st return wrap_stmt(out_node, out_child_scope, scope, trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope)); case ZigClangStmt_NoStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NoStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C NoStmtClass"); return ErrorUnexpected; case ZigClangStmt_GCCAsmStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GCCAsmStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GCCAsmStmtClass"); return ErrorUnexpected; case ZigClangStmt_MSAsmStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSAsmStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSAsmStmtClass"); return ErrorUnexpected; case ZigClangStmt_AttributedStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AttributedStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AttributedStmtClass"); return ErrorUnexpected; case ZigClangStmt_CXXCatchStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXCatchStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXCatchStmtClass"); return ErrorUnexpected; case ZigClangStmt_CXXForRangeStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXForRangeStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXForRangeStmtClass"); return ErrorUnexpected; case ZigClangStmt_CXXTryStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTryStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTryStmtClass"); return ErrorUnexpected; case ZigClangStmt_CapturedStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CapturedStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CapturedStmtClass"); return ErrorUnexpected; case ZigClangStmt_CoreturnStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoreturnStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoreturnStmtClass"); return ErrorUnexpected; case ZigClangStmt_CoroutineBodyStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoroutineBodyStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoroutineBodyStmtClass"); return ErrorUnexpected; case ZigClangStmt_BinaryConditionalOperatorClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BinaryConditionalOperatorClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BinaryConditionalOperatorClass"); return ErrorUnexpected; case ZigClangStmt_AddrLabelExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AddrLabelExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AddrLabelExprClass"); return ErrorUnexpected; case ZigClangStmt_ArrayInitIndexExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayInitIndexExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayInitIndexExprClass"); return ErrorUnexpected; case ZigClangStmt_ArrayInitLoopExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayInitLoopExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayInitLoopExprClass"); return ErrorUnexpected; case ZigClangStmt_ArrayTypeTraitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayTypeTraitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayTypeTraitExprClass"); return ErrorUnexpected; case ZigClangStmt_AsTypeExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AsTypeExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AsTypeExprClass"); return ErrorUnexpected; case ZigClangStmt_AtomicExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AtomicExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AtomicExprClass"); return ErrorUnexpected; case ZigClangStmt_BlockExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BlockExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BlockExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXBindTemporaryExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXBindTemporaryExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXBindTemporaryExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXBoolLiteralExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXBoolLiteralExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXBoolLiteralExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXConstructExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstructExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXConstructExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXTemporaryObjectExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTemporaryObjectExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTemporaryObjectExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXDefaultArgExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDefaultArgExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDefaultArgExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXDefaultInitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDefaultInitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDefaultInitExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXDeleteExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDeleteExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDeleteExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXDependentScopeMemberExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDependentScopeMemberExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDependentScopeMemberExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXFoldExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXFoldExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXFoldExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXInheritedCtorInitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXInheritedCtorInitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXInheritedCtorInitExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXNewExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNewExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNewExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXNoexceptExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNoexceptExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNoexceptExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXNullPtrLiteralExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNullPtrLiteralExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNullPtrLiteralExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXPseudoDestructorExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXPseudoDestructorExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXPseudoDestructorExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXScalarValueInitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXScalarValueInitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXScalarValueInitExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXStdInitializerListExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXStdInitializerListExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXStdInitializerListExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXThisExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXThisExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXThisExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXThrowExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXThrowExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXThrowExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXTypeidExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTypeidExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTypeidExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXUnresolvedConstructExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXUnresolvedConstructExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXUnresolvedConstructExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXUuidofExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXUuidofExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXUuidofExprClass"); return ErrorUnexpected; case ZigClangStmt_CUDAKernelCallExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CUDAKernelCallExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CUDAKernelCallExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXMemberCallExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXMemberCallExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXMemberCallExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXOperatorCallExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXOperatorCallExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXOperatorCallExprClass"); return ErrorUnexpected; case ZigClangStmt_UserDefinedLiteralClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UserDefinedLiteralClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UserDefinedLiteralClass"); return ErrorUnexpected; case ZigClangStmt_CXXFunctionalCastExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXFunctionalCastExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXFunctionalCastExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXConstCastExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstCastExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXConstCastExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXDynamicCastExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDynamicCastExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDynamicCastExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXReinterpretCastExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXReinterpretCastExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXReinterpretCastExprClass"); return ErrorUnexpected; case ZigClangStmt_CXXStaticCastExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXStaticCastExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXStaticCastExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCBridgedCastExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBridgedCastExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBridgedCastExprClass"); return ErrorUnexpected; case ZigClangStmt_CharacterLiteralClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CharacterLiteralClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CharacterLiteralClass"); return ErrorUnexpected; case ZigClangStmt_ChooseExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ChooseExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ChooseExprClass"); return ErrorUnexpected; case ZigClangStmt_CompoundLiteralExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CompoundLiteralExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CompoundLiteralExprClass"); return ErrorUnexpected; case ZigClangStmt_ConvertVectorExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ConvertVectorExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ConvertVectorExprClass"); return ErrorUnexpected; case ZigClangStmt_CoawaitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoawaitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoawaitExprClass"); return ErrorUnexpected; case ZigClangStmt_CoyieldExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoyieldExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoyieldExprClass"); return ErrorUnexpected; case ZigClangStmt_DependentCoawaitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DependentCoawaitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DependentCoawaitExprClass"); return ErrorUnexpected; case ZigClangStmt_DependentScopeDeclRefExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DependentScopeDeclRefExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DependentScopeDeclRefExprClass"); return ErrorUnexpected; case ZigClangStmt_DesignatedInitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DesignatedInitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DesignatedInitExprClass"); return ErrorUnexpected; case ZigClangStmt_DesignatedInitUpdateExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DesignatedInitUpdateExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DesignatedInitUpdateExprClass"); return ErrorUnexpected; case ZigClangStmt_ExpressionTraitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExpressionTraitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExpressionTraitExprClass"); return ErrorUnexpected; case ZigClangStmt_ExtVectorElementExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExtVectorElementExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExtVectorElementExprClass"); return ErrorUnexpected; case ZigClangStmt_FixedPointLiteralClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FixedPointLiteralClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FixedPointLiteralClass"); return ErrorUnexpected; case ZigClangStmt_FloatingLiteralClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FloatingLiteralClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FloatingLiteralClass"); return ErrorUnexpected; case ZigClangStmt_ExprWithCleanupsClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExprWithCleanupsClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExprWithCleanupsClass"); return ErrorUnexpected; case ZigClangStmt_FunctionParmPackExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FunctionParmPackExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FunctionParmPackExprClass"); return ErrorUnexpected; case ZigClangStmt_GNUNullExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GNUNullExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GNUNullExprClass"); return ErrorUnexpected; case ZigClangStmt_GenericSelectionExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GenericSelectionExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GenericSelectionExprClass"); return ErrorUnexpected; case ZigClangStmt_ImaginaryLiteralClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImaginaryLiteralClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ImaginaryLiteralClass"); return ErrorUnexpected; case ZigClangStmt_ImplicitValueInitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImplicitValueInitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ImplicitValueInitExprClass"); return ErrorUnexpected; case ZigClangStmt_InitListExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C InitListExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C InitListExprClass"); return ErrorUnexpected; case ZigClangStmt_LambdaExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LambdaExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C LambdaExprClass"); return ErrorUnexpected; case ZigClangStmt_MSPropertyRefExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSPropertyRefExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSPropertyRefExprClass"); return ErrorUnexpected; case ZigClangStmt_MSPropertySubscriptExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSPropertySubscriptExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSPropertySubscriptExprClass"); return ErrorUnexpected; case ZigClangStmt_MaterializeTemporaryExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MaterializeTemporaryExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MaterializeTemporaryExprClass"); return ErrorUnexpected; case ZigClangStmt_NoInitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NoInitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C NoInitExprClass"); return ErrorUnexpected; case ZigClangStmt_OMPArraySectionExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPArraySectionExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPArraySectionExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCArrayLiteralClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCArrayLiteralClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCArrayLiteralClass"); return ErrorUnexpected; case ZigClangStmt_ObjCAvailabilityCheckExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAvailabilityCheckExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAvailabilityCheckExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCBoolLiteralExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBoolLiteralExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBoolLiteralExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCBoxedExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBoxedExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBoxedExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCDictionaryLiteralClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCDictionaryLiteralClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCDictionaryLiteralClass"); return ErrorUnexpected; case ZigClangStmt_ObjCEncodeExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCEncodeExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCEncodeExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCIndirectCopyRestoreExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIndirectCopyRestoreExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIndirectCopyRestoreExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCIsaExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIsaExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIsaExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCIvarRefExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIvarRefExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIvarRefExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCMessageExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCMessageExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCMessageExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCPropertyRefExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCPropertyRefExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCPropertyRefExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCProtocolExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProtocolExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCProtocolExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCSelectorExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCSelectorExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCSelectorExprClass"); return ErrorUnexpected; case ZigClangStmt_ObjCStringLiteralClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCStringLiteralClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCStringLiteralClass"); return ErrorUnexpected; case ZigClangStmt_ObjCSubscriptRefExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCSubscriptRefExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCSubscriptRefExprClass"); return ErrorUnexpected; case ZigClangStmt_OffsetOfExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OffsetOfExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OffsetOfExprClass"); return ErrorUnexpected; case ZigClangStmt_OpaqueValueExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OpaqueValueExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OpaqueValueExprClass"); return ErrorUnexpected; case ZigClangStmt_UnresolvedLookupExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedLookupExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UnresolvedLookupExprClass"); return ErrorUnexpected; case ZigClangStmt_UnresolvedMemberExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedMemberExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UnresolvedMemberExprClass"); return ErrorUnexpected; case ZigClangStmt_PackExpansionExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PackExpansionExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C PackExpansionExprClass"); return ErrorUnexpected; case ZigClangStmt_ParenListExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ParenListExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ParenListExprClass"); return ErrorUnexpected; case ZigClangStmt_PseudoObjectExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PseudoObjectExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C PseudoObjectExprClass"); return ErrorUnexpected; case ZigClangStmt_ShuffleVectorExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ShuffleVectorExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ShuffleVectorExprClass"); return ErrorUnexpected; case ZigClangStmt_SizeOfPackExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SizeOfPackExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SizeOfPackExprClass"); return ErrorUnexpected; case ZigClangStmt_SubstNonTypeTemplateParmExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SubstNonTypeTemplateParmExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SubstNonTypeTemplateParmExprClass"); return ErrorUnexpected; case ZigClangStmt_SubstNonTypeTemplateParmPackExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SubstNonTypeTemplateParmPackExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SubstNonTypeTemplateParmPackExprClass"); return ErrorUnexpected; case ZigClangStmt_TypeTraitExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeTraitExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C TypeTraitExprClass"); return ErrorUnexpected; case ZigClangStmt_TypoExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypoExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C TypoExprClass"); return ErrorUnexpected; case ZigClangStmt_VAArgExprClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VAArgExprClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C VAArgExprClass"); return ErrorUnexpected; case ZigClangStmt_GotoStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GotoStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GotoStmtClass"); return ErrorUnexpected; case ZigClangStmt_IndirectGotoStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C IndirectGotoStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C IndirectGotoStmtClass"); return ErrorUnexpected; case ZigClangStmt_LabelStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LabelStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C LabelStmtClass"); return ErrorUnexpected; case ZigClangStmt_MSDependentExistsStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSDependentExistsStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSDependentExistsStmtClass"); return ErrorUnexpected; case ZigClangStmt_OMPAtomicDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPAtomicDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPAtomicDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPBarrierDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPBarrierDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPBarrierDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPCancelDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCancelDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCancelDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPCancellationPointDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCancellationPointDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCancellationPointDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPCriticalDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCriticalDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCriticalDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPFlushDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPFlushDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPFlushDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPDistributeDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPDistributeParallelForDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeParallelForDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeParallelForDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeParallelForSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPDistributeSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPForDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPForDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPForDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPForSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPForSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPForSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPParallelForDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelForDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelForDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPParallelForSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelForSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelForSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetParallelForSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelForSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelForSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTaskLoopDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskLoopDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskLoopDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTaskLoopSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskLoopSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskLoopSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTeamsDistributeDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeSimdDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeSimdDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPMasterDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPMasterDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPMasterDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPOrderedDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPOrderedDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPOrderedDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPParallelDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPParallelSectionsDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelSectionsDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelSectionsDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPSectionDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSectionDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSectionDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPSectionsDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSectionsDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSectionsDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPSingleDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSingleDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSingleDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetDataDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetDataDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetDataDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetEnterDataDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetEnterDataDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetEnterDataDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetExitDataDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetExitDataDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetExitDataDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetParallelDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetParallelForDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelForDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelForDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetTeamsDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTargetUpdateDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetUpdateDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetUpdateDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTaskDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTaskgroupDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskgroupDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskgroupDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTaskwaitDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskwaitDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskwaitDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTaskyieldDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskyieldDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskyieldDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_OMPTeamsDirectiveClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDirectiveClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDirectiveClass"); return ErrorUnexpected; case ZigClangStmt_ObjCAtCatchStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtCatchStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtCatchStmtClass"); return ErrorUnexpected; case ZigClangStmt_ObjCAtFinallyStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtFinallyStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtFinallyStmtClass"); return ErrorUnexpected; case ZigClangStmt_ObjCAtSynchronizedStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtSynchronizedStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtSynchronizedStmtClass"); return ErrorUnexpected; case ZigClangStmt_ObjCAtThrowStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtThrowStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtThrowStmtClass"); return ErrorUnexpected; case ZigClangStmt_ObjCAtTryStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtTryStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtTryStmtClass"); return ErrorUnexpected; case ZigClangStmt_ObjCAutoreleasePoolStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAutoreleasePoolStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAutoreleasePoolStmtClass"); return ErrorUnexpected; case ZigClangStmt_ObjCForCollectionStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCForCollectionStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCForCollectionStmtClass"); return ErrorUnexpected; case ZigClangStmt_SEHExceptStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHExceptStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHExceptStmtClass"); return ErrorUnexpected; case ZigClangStmt_SEHFinallyStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHFinallyStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHFinallyStmtClass"); return ErrorUnexpected; case ZigClangStmt_SEHLeaveStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHLeaveStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHLeaveStmtClass"); return ErrorUnexpected; case ZigClangStmt_SEHTryStmtClass: - emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHTryStmtClass"); + emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHTryStmtClass"); return ErrorUnexpected; } zig_unreachable(); @@ -3835,7 +3841,7 @@ static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope { AstNode *result_node; TransScope *result_scope; - if (trans_stmt_extra(c, scope, expr, result_used, lrval, &result_node, &result_scope, nullptr)) { + if (trans_stmt_extra(c, scope, (const ZigClangStmt *)expr, result_used, lrval, &result_node, &result_scope, nullptr)) { return nullptr; } return result_node; @@ -3843,7 +3849,7 @@ static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope // Statements have no result and no concept of L or R value. // Returns child scope, or null if there was an error -static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node) { +static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node) { TransScope *child_scope; if (trans_stmt_extra(c, scope, stmt, ResultUsedNo, TransRValue, out_node, &child_scope, nullptr)) { return nullptr; @@ -3913,7 +3919,7 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) { // actual function definition with body c->ptr_params.clear(); - clang::Stmt *body = fn_decl->getBody(); + const ZigClangStmt *body = bitcast(fn_decl->getBody()); AstNode *actual_body_node; TransScope *result_scope = trans_stmt(c, scope, body, &actual_body_node); if (result_scope == nullptr) { diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index c892426363..003fd0cc7d 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -871,3 +871,17 @@ const char *ZigClangType_getTypeClassName(const ZigClangType *self) { return casted->getTypeClassName(); } +ZigClangSourceLocation ZigClangStmt_getBeginLoc(const ZigClangStmt *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getBeginLoc()); +} + +bool ZigClangStmt_classof_Expr(const ZigClangStmt *self) { + auto casted = reinterpret_cast(self); + return clang::Expr::classof(casted); +} + +ZigClangStmtClass ZigClangStmt_getStmtClass(const ZigClangStmt *self) { + auto casted = reinterpret_cast(self); + return (ZigClangStmtClass)casted->getStmtClass(); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 6f3f14a4e1..544cc7e4d7 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -547,4 +547,9 @@ 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); + #endif From ea5518f69edc51e8e70c2c4d4c4daa3ad9bcb242 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 13 Apr 2019 12:31:45 +0200 Subject: [PATCH 044/285] make os_file_close poison file handle after close This helps track down use-after-close bugs. --- src/cache_hash.cpp | 24 ++++++++++++------------ src/os.cpp | 8 +++++--- src/os.hpp | 2 +- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/cache_hash.cpp b/src/cache_hash.cpp index 1f25a9982e..250733ec92 100644 --- a/src/cache_hash.cpp +++ b/src/cache_hash.cpp @@ -256,10 +256,10 @@ static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf, Buf *contents } if ((err = hash_file(chf->bin_digest, this_file, contents))) { - os_file_close(this_file); + os_file_close(&this_file); return err; } - os_file_close(this_file); + os_file_close(&this_file); blake2b_update(&ch->blake, chf->bin_digest, 48); @@ -300,7 +300,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) { Buf line_buf = BUF_INIT; buf_resize(&line_buf, 512); if ((err = os_file_read_all(ch->manifest_file, &line_buf))) { - os_file_close(ch->manifest_file); + os_file_close(&ch->manifest_file); return err; } @@ -389,14 +389,14 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) { OsFileAttr actual_attr; if ((err = os_file_open_r(chf->path, &this_file, &actual_attr))) { fprintf(stderr, "Unable to open %s\n: %s", buf_ptr(chf->path), err_str(err)); - os_file_close(ch->manifest_file); + os_file_close(&ch->manifest_file); return ErrorCacheUnavailable; } if (chf->attr.mtime.sec == actual_attr.mtime.sec && chf->attr.mtime.nsec == actual_attr.mtime.nsec && chf->attr.inode == actual_attr.inode) { - os_file_close(this_file); + os_file_close(&this_file); } else { // we have to recompute the digest. // later we'll rewrite the manifest with the new mtime/digest values @@ -411,11 +411,11 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) { uint8_t actual_digest[48]; if ((err = hash_file(actual_digest, this_file, nullptr))) { - os_file_close(this_file); - os_file_close(ch->manifest_file); + os_file_close(&this_file); + os_file_close(&ch->manifest_file); return err; } - os_file_close(this_file); + os_file_close(&this_file); if (memcmp(chf->bin_digest, actual_digest, 48) != 0) { memcpy(chf->bin_digest, actual_digest, 48); // keep going until we have the input file digests @@ -433,12 +433,12 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) { CacheHashFile *chf = &ch->files.at(file_i); if ((err = populate_file_hash(ch, chf, nullptr))) { fprintf(stderr, "Unable to hash %s: %s\n", buf_ptr(chf->path), err_str(err)); - os_file_close(ch->manifest_file); + os_file_close(&ch->manifest_file); return ErrorCacheUnavailable; } } if (return_code != ErrorNone) { - os_file_close(ch->manifest_file); + os_file_close(&ch->manifest_file); } return return_code; } @@ -453,7 +453,7 @@ Error cache_add_file_fetch(CacheHash *ch, Buf *resolved_path, Buf *contents) { CacheHashFile *chf = ch->files.add_one(); chf->path = resolved_path; if ((err = populate_file_hash(ch, chf, contents))) { - os_file_close(ch->manifest_file); + os_file_close(&ch->manifest_file); return err; } @@ -586,6 +586,6 @@ void cache_release(CacheHash *ch) { } } - os_file_close(ch->manifest_file); + os_file_close(&ch->manifest_file); } diff --git a/src/os.cpp b/src/os.cpp index 470d222307..60c66908cc 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -2081,11 +2081,13 @@ Error os_file_overwrite(OsFile file, Buf *contents) { #endif } -void os_file_close(OsFile file) { +void os_file_close(OsFile *file) { #if defined(ZIG_OS_WINDOWS) - CloseHandle(file); + CloseHandle(*file); + *file = NULL; #else - close(file); + close(*file); + *file = -1; #endif } diff --git a/src/os.hpp b/src/os.hpp index 5064a6444c..b301937e83 100644 --- a/src/os.hpp +++ b/src/os.hpp @@ -121,7 +121,7 @@ Error ATTRIBUTE_MUST_USE os_file_open_lock_rw(Buf *full_path, OsFile *out_file); Error ATTRIBUTE_MUST_USE os_file_read(OsFile file, void *ptr, size_t *len); Error ATTRIBUTE_MUST_USE os_file_read_all(OsFile file, Buf *contents); Error ATTRIBUTE_MUST_USE os_file_overwrite(OsFile file, Buf *contents); -void os_file_close(OsFile file); +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); From 93e89b3b7efeaa41f4f11fbb022b962d2244dab2 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 13 Apr 2019 12:33:29 +0200 Subject: [PATCH 045/285] don't close cache manifest file prematurely ErrorInvalidFormat is not a fatal error so don't close the cache manifest file right away but instead let cache_final() handle it. Fixes the following (very common) warning when running the test suite: Warning: Unable to write cache file [..]: unexpected seek failure The seek failure is an lseek() system call that failed with EBADF because the file descriptor had already been closed. --- src/cache_hash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cache_hash.cpp b/src/cache_hash.cpp index 250733ec92..efb1a06b59 100644 --- a/src/cache_hash.cpp +++ b/src/cache_hash.cpp @@ -437,7 +437,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) { return ErrorCacheUnavailable; } } - if (return_code != ErrorNone) { + if (return_code != ErrorNone && return_code != ErrorInvalidFormat) { os_file_close(&ch->manifest_file); } return return_code; From 72bcd5a4a50787b0407c21e61d660e59fa74e449 Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Sat, 13 Apr 2019 15:15:39 -0500 Subject: [PATCH 046/285] WIP: hello world --- std/os.zig | 5 +- std/os/wasi.zig | 105 ++++++++++++++++++++++++++++++++++++++ std/os/wasi/core.zig | 12 +++++ std/special/bootstrap.zig | 12 +++++ std/special/panic.zig | 5 +- 5 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 std/os/wasi.zig create mode 100644 std/os/wasi/core.zig diff --git a/std/os.zig b/std/os.zig index d641cf29c9..c1d5aa4096 100644 --- a/std/os.zig +++ b/std/os.zig @@ -23,6 +23,7 @@ test "std.os" { _ = @import("os/time.zig"); _ = @import("os/windows.zig"); _ = @import("os/uefi.zig"); + _ = @import("os/wasi.zig"); _ = @import("os/get_app_data_dir.zig"); } @@ -33,6 +34,7 @@ pub const freebsd = @import("os/freebsd.zig"); pub const netbsd = @import("os/netbsd.zig"); pub const zen = @import("os/zen.zig"); pub const uefi = @import("os/uefi.zig"); +pub const wasi = @import("os/wasi.zig"); pub const posix = switch (builtin.os) { Os.linux => linux, @@ -40,6 +42,7 @@ pub const posix = switch (builtin.os) { Os.freebsd => freebsd, Os.netbsd => netbsd, Os.zen => zen, + Os.wasi => wasi, else => @compileError("Unsupported OS"), }; @@ -187,7 +190,7 @@ pub fn abort() noreturn { c.abort(); } switch (builtin.os) { - Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => { + Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd, Os.wasi => { _ = posix.raise(posix.SIGABRT); _ = posix.raise(posix.SIGKILL); while (true) {} diff --git a/std/os/wasi.zig b/std/os/wasi.zig new file mode 100644 index 0000000000..458669529c --- /dev/null +++ b/std/os/wasi.zig @@ -0,0 +1,105 @@ +use @import("wasi/core.zig"); + +pub const STDIN_FILENO = 0; +pub const STDOUT_FILENO = 1; +pub const STDERR_FILENO = 2; + +pub const ESUCCESS = 0; +pub const E2BIG = 1; +pub const EACCES = 2; +pub const EADDRINUSE = 3; +pub const EADDRNOTAVAIL = 4; +pub const EAFNOSUPPORT = 5; +pub const EAGAIN = 6; +pub const EALREADY = 7; +pub const EBADF = 8; +pub const EBADMSG = 9; +pub const EBUSY = 10; +pub const ECANCELED = 11; +pub const ECHILD = 12; +pub const ECONNABORTED = 13; +pub const ECONNREFUSED = 14; +pub const ECONNRESET = 15; +pub const EDEADLK = 16; +pub const EDESTADDRREQ = 17; +pub const EDOM = 18; +pub const EDQUOT = 19; +pub const EEXIST = 20; +pub const EFAULT = 21; +pub const EFBIG = 22; +pub const EHOSTUNREACH = 23; +pub const EIDRM = 24; +pub const EILSEQ = 25; +pub const EINPROGRESS = 26; +pub const EINTR = 27; +pub const EINVAL = 28; +pub const EIO = 29; +pub const EISCONN = 30; +pub const EISDIR = 31; +pub const ELOOP = 32; +pub const EMFILE = 33; +pub const EMLINK = 34; +pub const EMSGSIZE = 35; +pub const EMULTIHOP = 36; +pub const ENAMETOOLONG = 37; +pub const ENETDOWN = 38; +pub const ENETRESET = 39; +pub const ENETUNREACH = 40; +pub const ENFILE = 41; +pub const ENOBUFS = 42; +pub const ENODEV = 43; +pub const ENOENT = 44; +pub const ENOEXEC = 45; +pub const ENOLCK = 46; +pub const ENOLINK = 47; +pub const ENOMEM = 48; +pub const ENOMSG = 49; +pub const ENOPROTOOPT = 50; +pub const ENOSPC = 51; +pub const ENOSYS = 52; +pub const ENOTCONN = 53; +pub const ENOTDIR = 54; +pub const ENOTEMPTY = 55; +pub const ENOTRECOVERABLE = 56; +pub const ENOTSOCK = 57; +pub const ENOTSUP = 58; +pub const ENOTTY = 59; +pub const ENXIO = 60; +pub const EOVERFLOW = 61; +pub const EOWNERDEAD = 62; +pub const EPERM = 63; +pub const EPIPE = 64; +pub const EPROTO = 65; +pub const EPROTONOSUPPORT = 66; +pub const EPROTOTYPE = 67; +pub const ERANGE = 68; +pub const EROFS = 69; +pub const ESPIPE = 70; +pub const ESRCH = 71; +pub const ESTALE = 72; +pub const ETIMEDOUT = 73; +pub const ETXTBSY = 74; +pub const EXDEV = 75; +pub const ENOTCAPABLE = 76; + +// TODO: figure out what's going on here +pub fn getErrno(r: usize) usize { + const signed_r = @bitCast(isize, r); + return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0; +} + +pub fn exit(status: i32) noreturn { + __wasi_proc_exit(@bitCast(__wasi_exitcode_t, isize(status))); +} + +pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { + var nwritten: usize = undefined; + + const iovs = []__wasi_ciovec_t{__wasi_ciovec_t{ + .buf = buf, + .buf_len = count, + }}; + + _ = __wasi_fd_write(@bitCast(__wasi_fd_t, isize(fd)), &iovs[0], iovs.len, &nwritten); + return nwritten; +} diff --git a/std/os/wasi/core.zig b/std/os/wasi/core.zig new file mode 100644 index 0000000000..329d8f8fc2 --- /dev/null +++ b/std/os/wasi/core.zig @@ -0,0 +1,12 @@ +pub const __wasi_errno_t = u16; +pub const __wasi_exitcode_t = u32; +pub const __wasi_fd_t = u32; + +pub const __wasi_ciovec_t = extern struct { + buf: [*]const u8, + buf_len: usize, +}; + +pub extern fn __wasi_proc_exit(rval: __wasi_exitcode_t) noreturn; + +pub extern fn __wasi_fd_write(fd: __wasi_fd_t, iovs: *const __wasi_ciovec_t, iovs_len: usize, nwritten: *usize) __wasi_errno_t; diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index 32f913a5b0..e93a85861d 100644 --- a/std/special/bootstrap.zig +++ b/std/special/bootstrap.zig @@ -14,6 +14,8 @@ comptime { @export("main", main, strong_linkage); } else if (builtin.os == builtin.Os.windows) { @export("WinMainCRTStartup", WinMainCRTStartup, strong_linkage); + } else if (builtin.os == builtin.Os.wasi) { + @export("_start", wasiStart, strong_linkage); } else { @export("_start", _start, strong_linkage); } @@ -43,6 +45,16 @@ nakedcc fn _start() noreturn { @noInlineCall(posixCallMainAndExit); } +nakedcc fn wasiStart() noreturn { + // TODO: Decide if alloc at init is acceptable for args and env + // @llvm.wasm.mem.grow.i32 + // __wasi_args_get() + // __wasi_args_sizes_get() + // __wasi_environ_get() + // __wasi_environ_sizes_get() + std.os.posix.exit(callMain()); +} + extern fn WinMainCRTStartup() noreturn { @setAlignStack(16); if (!builtin.single_threaded) { diff --git a/std/special/panic.zig b/std/special/panic.zig index 7cb7143955..1d459665c4 100644 --- a/std/special/panic.zig +++ b/std/special/panic.zig @@ -9,8 +9,9 @@ const std = @import("std"); pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { @setCold(true); switch (builtin.os) { - // TODO: fix panic in zen. - builtin.Os.freestanding, builtin.Os.zen => { + // TODO: fix panic in zen + // TODO: fix panic in wasi + builtin.Os.freestanding, builtin.Os.zen, builtin.Os.wasi => { while (true) {} }, builtin.Os.uefi => { From a43fd7a550c3cae7443f09e4294cfccb6bdf0320 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sat, 13 Apr 2019 11:43:40 +1200 Subject: [PATCH 047/285] Add favicon to langref.html --- doc/langref.html.in | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/langref.html.in b/doc/langref.html.in index a73e5d94d9..d1d8e0aa77 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -4,6 +4,7 @@ Documentation - The Zig Programming Language +