mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-26 13:01:34 +03:00
@@ -6,7 +6,7 @@ contact_links:
|
||||
about: "Please use one of the community spaces instead for questions or general discussions."
|
||||
url: https://ziglang.org/community
|
||||
- name: C Translation
|
||||
about: "Issues related to `zig translate-c` and `@cImport` are tracked separately."
|
||||
about: "Issues related to `zig translate-c` are tracked separately."
|
||||
url: https://codeberg.org/ziglang/translate-c
|
||||
- name: Copilot and Other LLMs
|
||||
about: "Please do not use GitHub Copilot or any other LLM to write an issue."
|
||||
|
||||
@@ -735,11 +735,6 @@ if(MSVC OR MINGW)
|
||||
endif()
|
||||
|
||||
|
||||
# "-Dno-langref" is hardcoded because stage2 builds lack the `@cImport`
|
||||
# feature, which some of the doctests rely on.
|
||||
|
||||
# To obtain this document, run `zig build` against stage3 rather than stage2.
|
||||
# Note that the `langref` step can be used to isolate this task.
|
||||
set(ZIG_BUILD_ARGS
|
||||
--zig-lib-dir "${PROJECT_SOURCE_DIR}/lib"
|
||||
|
||||
@@ -749,8 +744,6 @@ set(ZIG_BUILD_ARGS
|
||||
|
||||
-Denable-llvm
|
||||
"-Dconfig_h=${ZIG_CONFIG_H_OUT}"
|
||||
|
||||
-Dno-langref
|
||||
)
|
||||
|
||||
set(ZIG_EXTRA_BUILD_ARGS "" CACHE STRING "Extra zig build args")
|
||||
|
||||
@@ -658,38 +658,31 @@ WebAssembly-related.
|
||||
|
||||
### Improving Translate-C
|
||||
|
||||
`translate-c` is a feature provided by Zig that converts C source code into
|
||||
Zig source code. It powers the `zig translate-c` command as well as
|
||||
[@cImport](https://ziglang.org/documentation/master/#cImport), allowing Zig
|
||||
code to not only take advantage of function prototypes defined in .h files,
|
||||
but also `static inline` functions written in C, and even some macros.
|
||||
`translate-c` is a feature provided by Zig that converts C source code into Zig
|
||||
source code. It powers the `zig translate-c` command, allowing Zig code to not
|
||||
only take advantage of function prototypes defined in C header files, but also
|
||||
`static inline` functions written in C, and even some macros.
|
||||
|
||||
This feature used to work by using libclang API to parse and semantically
|
||||
analyze C/C++ files, and then based on the provided AST and type information,
|
||||
generating Zig AST, and finally using the mechanisms of `zig fmt` to render the
|
||||
Zig AST to a file.
|
||||
|
||||
However, C translation is in a transitional period right now. It used to be
|
||||
based on Clang, but is now based on Aro:
|
||||
However, it is now based on [arocc](https://github.com/Vexu/arocc/), a
|
||||
third-party C compiler written in Zig. Test coverage, bug reports, and official
|
||||
implementation live in this repository: [ziglang/translate-c](https://codeberg.org/ziglang/translate-c/)
|
||||
|
||||
[Pull Request: update aro and translate-c to latest; delete clang translate-c](https://github.com/ziglang/zig/pull/24497)
|
||||
|
||||
Test coverage as well as bug reports have been moved to this repository:
|
||||
|
||||
[ziglang/translate-c](https://codeberg.org/ziglang/translate-c/)
|
||||
|
||||
In the future, [@cImport will move to the build system](https://github.com/ziglang/zig/issues/20630),
|
||||
but for now, the translate-c logic is copy-pasted from that project into
|
||||
[ziglang/zig](https://codeberg.org/ziglang/zig/), powering both `zig translate-c`
|
||||
and `@cImport`.
|
||||
This package is currently vendored into the Zig source tree. The TranslateC
|
||||
build step takes advantage of this to provide the ability to setup C
|
||||
translation in one's build.zig script.
|
||||
|
||||
Please see the readme of the translate-c project for how to contribute. Once an
|
||||
issue is resolved (and test coverage added) there, the changes can be
|
||||
immediately backported to the zig compiler.
|
||||
|
||||
Once we fix the problems people are facing from this transition from Clang to
|
||||
Aro, we can move on to enhancing the translate-c package such that `@cImport`
|
||||
becomes redundant and can therefore be eliminated from the language.
|
||||
However, in the future, this build step will be removed in favor of explicit
|
||||
dependency on the translate-c package via build system / package manager. At
|
||||
that point, Zig will stop vendoring arocc.
|
||||
|
||||
### Autodoc
|
||||
|
||||
|
||||
+2
-163
@@ -1032,9 +1032,8 @@
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Local Variables#}
|
||||
<p>
|
||||
Local variables occur inside {#link|Functions#}, {#link|comptime#} blocks, and {#link|@cImport#} blocks.
|
||||
</p>
|
||||
<p>Local variables occur inside {#link|Functions#}, {#link|comptime#}
|
||||
blocks, and labeled {#link|Blocks#}.</p>
|
||||
<p>
|
||||
When a local variable is {#syntax#}const{#endsyntax#}, it means that after initialization, the variable's
|
||||
value will not change. If the initialization value of a {#syntax#}const{#endsyntax#} variable is
|
||||
@@ -4573,62 +4572,6 @@ comptime {
|
||||
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@cDefine#}
|
||||
<pre>{#syntax#}@cDefine(comptime name: []const u8, value) void{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
This appends <code>#define $name $value</code> to the {#syntax#}@cImport{#endsyntax#}
|
||||
temporary buffer.
|
||||
</p>
|
||||
<p>
|
||||
To define without a value, like this:
|
||||
</p>
|
||||
<pre><code class="c">#define _GNU_SOURCE</code></pre>
|
||||
<p>
|
||||
Use the void value, like this:
|
||||
</p>
|
||||
<pre>{#syntax#}@cDefine("_GNU_SOURCE", {}){#endsyntax#}</pre>
|
||||
{#see_also|Import from C Header File|@cInclude|@cImport|@cUndef|void#}
|
||||
{#header_close#}
|
||||
{#header_open|@cImport#}
|
||||
<pre>{#syntax#}@cImport(expression) type{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function parses C code and imports the functions, types, variables,
|
||||
and compatible macro definitions into a new empty struct type, and then
|
||||
returns that type.
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}expression{#endsyntax#} is interpreted at compile time. The builtin functions
|
||||
{#syntax#}@cInclude{#endsyntax#}, {#syntax#}@cDefine{#endsyntax#}, and {#syntax#}@cUndef{#endsyntax#} work
|
||||
within this expression, appending to a temporary buffer which is then parsed as C code.
|
||||
</p>
|
||||
<p>
|
||||
Usually you should only have one {#syntax#}@cImport{#endsyntax#} in your entire application, because it saves the compiler
|
||||
from invoking clang multiple times, and prevents inline functions from being duplicated.
|
||||
</p>
|
||||
<p>
|
||||
Reasons for having multiple {#syntax#}@cImport{#endsyntax#} expressions would be:
|
||||
</p>
|
||||
<ul>
|
||||
<li>To avoid a symbol collision, for example if foo.h and bar.h both <code>#define CONNECTION_COUNT</code></li>
|
||||
<li>To analyze the C code with different preprocessor defines</li>
|
||||
</ul>
|
||||
{#see_also|Import from C Header File|@cInclude|@cDefine|@cUndef#}
|
||||
{#header_close#}
|
||||
{#header_open|@cInclude#}
|
||||
<pre>{#syntax#}@cInclude(comptime path: []const u8) void{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
This appends <code>#include <$path>\n</code> to the {#syntax#}c_import{#endsyntax#}
|
||||
temporary buffer.
|
||||
</p>
|
||||
{#see_also|Import from C Header File|@cImport|@cDefine|@cUndef#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@clz#}
|
||||
<pre>{#syntax#}@clz(operand: anytype) anytype{#endsyntax#}</pre>
|
||||
<p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>
|
||||
@@ -4758,18 +4701,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
{#see_also|@clz|@popCount#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@cUndef#}
|
||||
<pre>{#syntax#}@cUndef(comptime name: []const u8) void{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
This appends <code>#undef $name</code> to the {#syntax#}@cImport{#endsyntax#}
|
||||
temporary buffer.
|
||||
</p>
|
||||
{#see_also|Import from C Header File|@cImport|@cDefine|@cInclude#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@cVaArg#}
|
||||
<pre>{#syntax#}@cVaArg(operand: *std.builtin.VaList, comptime T: type) T{#endsyntax#}</pre>
|
||||
<p>
|
||||
@@ -6784,35 +6715,6 @@ const builtin = @import("builtin");
|
||||
</p>
|
||||
{#see_also|Primitive Types#}
|
||||
{#header_close#}
|
||||
{#header_open|Import from C Header File#}
|
||||
<p>
|
||||
The {#syntax#}@cImport{#endsyntax#} builtin function can be used
|
||||
to directly import symbols from <code class="file">.h</code> files:
|
||||
</p>
|
||||
{#code|cImport_builtin.zig#}
|
||||
|
||||
<p>
|
||||
The {#syntax#}@cImport{#endsyntax#} function takes an expression as a parameter.
|
||||
This expression is evaluated at compile-time and is used to control
|
||||
preprocessor directives and include multiple <code class="file">.h</code> files:
|
||||
</p>
|
||||
{#syntax_block|zig|@cImport Expression#}
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const c = @cImport({
|
||||
@cDefine("NDEBUG", builtin.mode == .ReleaseFast);
|
||||
if (something) {
|
||||
@cDefine("_GNU_SOURCE", {});
|
||||
}
|
||||
@cInclude("stdlib.h");
|
||||
if (something) {
|
||||
@cUndef("_GNU_SOURCE");
|
||||
}
|
||||
@cInclude("soundio.h");
|
||||
});
|
||||
{#end_syntax_block#}
|
||||
{#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|C Translation CLI#}
|
||||
<p>
|
||||
@@ -6872,42 +6774,8 @@ $ zig translate-c -cflags -fshort-enums -- varycflags.h|grep -B1 do_something
|
||||
pub const enum_FOO = u8;
|
||||
pub extern fn do_something(foo: enum_FOO) c_int;{#end_shell_samp#}
|
||||
{#header_close#}
|
||||
{#header_open|@cImport vs translate-c#}
|
||||
<p>{#syntax#}@cImport{#endsyntax#} and <kbd>zig translate-c</kbd> use the same underlying
|
||||
C translation functionality, so on a technical level they are equivalent. In practice,
|
||||
{#syntax#}@cImport{#endsyntax#} is useful as a way to quickly and easily access numeric constants, typedefs,
|
||||
and record types without needing any extra setup. If you need to pass {#link|cflags|Using -target and -cflags#}
|
||||
to clang, or if you would like to edit the translated code, it is recommended to use
|
||||
<kbd>zig translate-c</kbd> and save the results to a file. Common reasons for editing
|
||||
the generated code include: changing {#syntax#}anytype{#endsyntax#} parameters in function-like macros to more
|
||||
specific types; changing {#syntax#}[*c]T{#endsyntax#} pointers to {#syntax#}[*]T{#endsyntax#} or
|
||||
{#syntax#}*T{#endsyntax#} pointers for improved type safety; and
|
||||
{#link|enabling or disabling runtime safety|@setRuntimeSafety#} within specific functions.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#see_also|Targets|C Type Primitives|Pointers|C Pointers|Import from C Header File|@cInclude|@cImport|@setRuntimeSafety#}
|
||||
{#header_close#}
|
||||
{#header_open|C Translation Caching#}
|
||||
<p>
|
||||
The C translation feature (whether used via <kbd>zig translate-c</kbd> or
|
||||
{#syntax#}@cImport{#endsyntax#}) integrates with the Zig caching system. Subsequent runs with
|
||||
the same source file, target, and cflags will use the cache instead of repeatedly translating
|
||||
the same code.
|
||||
</p>
|
||||
<p>
|
||||
To see where the cached files are stored when compiling code that uses {#syntax#}@cImport{#endsyntax#},
|
||||
use the <kbd>--verbose-cimport</kbd> flag:
|
||||
</p>
|
||||
{#code|verbose_cimport_flag.zig#}
|
||||
|
||||
<p>
|
||||
<code class="file">cimport.h</code> contains the file to translate (constructed from calls to
|
||||
{#syntax#}@cInclude{#endsyntax#}, {#syntax#}@cDefine{#endsyntax#}, and {#syntax#}@cUndef{#endsyntax#}),
|
||||
<code class="file">cimport.h.d</code> is the list of file dependencies, and
|
||||
<code class="file">cimport.zig</code> contains the translated output.
|
||||
</p>
|
||||
{#see_also|Import from C Header File|C Translation CLI|@cInclude|@cImport#}
|
||||
{#header_close#}
|
||||
{#header_open|Translation failures#}
|
||||
<p>
|
||||
Some C constructs cannot be translated to Zig - for example, <em>goto</em>,
|
||||
@@ -6933,35 +6801,6 @@ pub extern fn do_something(foo: enum_FOO) c_int;{#end_shell_samp#}
|
||||
</p>
|
||||
{#see_also|opaque|extern|@compileError#}
|
||||
{#header_close#}
|
||||
{#header_open|C Macros#}
|
||||
<p>
|
||||
C Translation makes a best-effort attempt to translate function-like macros into equivalent
|
||||
Zig functions. Since C macros operate at the level of lexical tokens, not all C macros
|
||||
can be translated to Zig. Macros that cannot be translated will be demoted to
|
||||
{#syntax#}@compileError{#endsyntax#}. Note that C code which <em>uses</em> macros will be
|
||||
translated without any additional issues (since Zig operates on the pre-processed source
|
||||
with macros expanded). It is merely the macros themselves which may not be translatable to
|
||||
Zig.
|
||||
</p>
|
||||
<p>Consider the following example:</p>
|
||||
{#syntax_block|c|macro.c#}
|
||||
#define MAKELOCAL(NAME, INIT) int NAME = INIT
|
||||
int foo(void) {
|
||||
MAKELOCAL(a, 1);
|
||||
MAKELOCAL(b, 2);
|
||||
return a + b;
|
||||
}
|
||||
{#end_syntax_block#}
|
||||
{#shell_samp#}$ zig translate-c macro.c > macro.zig{#end_shell_samp#}
|
||||
{#code|macro.zig#}
|
||||
|
||||
<p>Note that {#syntax#}foo{#endsyntax#} was translated correctly despite using a non-translatable
|
||||
macro. {#syntax#}MAKELOCAL{#endsyntax#} was demoted to {#syntax#}@compileError{#endsyntax#} since
|
||||
it cannot be expressed as a Zig function; this simply means that you cannot directly use
|
||||
{#syntax#}MAKELOCAL{#endsyntax#} from Zig.
|
||||
</p>
|
||||
{#see_also|@compileError#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|C Pointers#}
|
||||
<p>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
const c = @cImport({
|
||||
// See https://github.com/ziglang/zig/issues/515
|
||||
@cDefine("_NO_CRT_STDIO_INLINE", "1");
|
||||
@cInclude("stdio.h");
|
||||
});
|
||||
pub fn main() void {
|
||||
if (@import("builtin").os.tag == .netbsd) return; // https://github.com/Vexu/arocc/issues/960
|
||||
_ = c.printf("hello\n");
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
// link_libc
|
||||
@@ -1,10 +0,0 @@
|
||||
pub export fn foo() c_int {
|
||||
var a: c_int = 1;
|
||||
_ = &a;
|
||||
var b: c_int = 2;
|
||||
_ = &b;
|
||||
return a + b;
|
||||
}
|
||||
pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected token .Equal"); // macro.c:1:9
|
||||
|
||||
// syntax
|
||||
@@ -10,4 +10,3 @@ test "variadic function" {
|
||||
|
||||
// test
|
||||
// link_libc
|
||||
// verbose_cimport
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
const c = @cImport({
|
||||
@cDefine("_NO_CRT_STDIO_INLINE", "1");
|
||||
@cInclude("stdio.h");
|
||||
});
|
||||
pub fn main() void {
|
||||
if (@import("builtin").os.tag == .netbsd) return; // https://github.com/Vexu/arocc/issues/960
|
||||
_ = c;
|
||||
}
|
||||
|
||||
// exe=succeed
|
||||
// link_libc
|
||||
// verbose_cimport
|
||||
@@ -333,8 +333,6 @@ pub fn main(init: process.Init.Minimal) !void {
|
||||
builder.verbose_llvm_ir = arg["--verbose-llvm-ir=".len..];
|
||||
} else if (mem.startsWith(u8, arg, "--verbose-llvm-bc=")) {
|
||||
builder.verbose_llvm_bc = arg["--verbose-llvm-bc=".len..];
|
||||
} else if (mem.eql(u8, arg, "--verbose-cimport")) {
|
||||
builder.verbose_cimport = true;
|
||||
} else if (mem.eql(u8, arg, "--verbose-cc")) {
|
||||
builder.verbose_cc = true;
|
||||
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
||||
|
||||
@@ -38,7 +38,6 @@ verbose_cc: bool,
|
||||
verbose_air: bool,
|
||||
verbose_llvm_ir: ?[]const u8,
|
||||
verbose_llvm_bc: ?[]const u8,
|
||||
verbose_cimport: bool,
|
||||
verbose_llvm_cpu_features: bool,
|
||||
reference_trace: ?u32 = null,
|
||||
invalid_user_input: bool,
|
||||
@@ -278,7 +277,6 @@ pub fn create(
|
||||
.verbose_air = false,
|
||||
.verbose_llvm_ir = null,
|
||||
.verbose_llvm_bc = null,
|
||||
.verbose_cimport = false,
|
||||
.verbose_llvm_cpu_features = false,
|
||||
.invalid_user_input = false,
|
||||
.allocator = arena,
|
||||
@@ -377,7 +375,6 @@ fn createChildOnly(
|
||||
.verbose_air = parent.verbose_air,
|
||||
.verbose_llvm_ir = parent.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = parent.verbose_llvm_bc,
|
||||
.verbose_cimport = parent.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features,
|
||||
.reference_trace = parent.reference_trace,
|
||||
.invalid_user_input = false,
|
||||
|
||||
@@ -1393,7 +1393,6 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
|
||||
try zig_args.append("--debug-incremental");
|
||||
}
|
||||
|
||||
if (b.verbose_cimport) try zig_args.append("--verbose-cimport");
|
||||
if (b.verbose_air) try zig_args.append("--verbose-air");
|
||||
if (b.verbose_llvm_ir) |path| try zig_args.append(b.fmt("--verbose-llvm-ir={s}", .{path}));
|
||||
if (b.verbose_llvm_bc) |path| try zig_args.append(b.fmt("--verbose-llvm-bc={s}", .{path}));
|
||||
|
||||
@@ -796,11 +796,6 @@ pub const SimpleComptimeReason = enum(u32) {
|
||||
operand_branchHint,
|
||||
operand_setRuntimeSafety,
|
||||
operand_embedFile,
|
||||
operand_cImport,
|
||||
operand_cDefine_macro_name,
|
||||
operand_cDefine_macro_value,
|
||||
operand_cInclude_file_name,
|
||||
operand_cUndef_macro_name,
|
||||
operand_shuffle_mask,
|
||||
operand_atomicRmw_operation,
|
||||
operand_reduce_operation,
|
||||
@@ -891,11 +886,6 @@ pub const SimpleComptimeReason = enum(u32) {
|
||||
.operand_branchHint => "operand to '@branchHint' must be comptime-known",
|
||||
.operand_setRuntimeSafety => "operand to '@setRuntimeSafety' must be comptime-known",
|
||||
.operand_embedFile => "operand to '@embedFile' must be comptime-known",
|
||||
.operand_cImport => "operand to '@cImport' is evaluated at comptime",
|
||||
.operand_cDefine_macro_name => "'@cDefine' macro name must be comptime-known",
|
||||
.operand_cDefine_macro_value => "'@cDefine' macro value must be comptime-known",
|
||||
.operand_cInclude_file_name => "'@cInclude' file name must be comptime-known",
|
||||
.operand_cUndef_macro_name => "'@cUndef' macro name must be comptime-known",
|
||||
.operand_shuffle_mask => "'@shuffle' mask must be comptime-known",
|
||||
.operand_atomicRmw_operation => "'@atomicRmw' operation must be comptime-known",
|
||||
.operand_reduce_operation => "'@reduce' operation must be comptime-known",
|
||||
|
||||
+1
-74
@@ -2870,7 +2870,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
|
||||
.mul_add,
|
||||
.max,
|
||||
.min,
|
||||
.c_import,
|
||||
.@"resume",
|
||||
.ret_err_value_code,
|
||||
.ret_ptr,
|
||||
@@ -8955,7 +8954,6 @@ fn typeOf(
|
||||
var typeof_scope = gz.makeSubBlock(scope);
|
||||
typeof_scope.is_comptime = false;
|
||||
typeof_scope.is_typeof = true;
|
||||
typeof_scope.c_import = false;
|
||||
defer typeof_scope.unstack();
|
||||
|
||||
const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, args[0], node);
|
||||
@@ -9055,8 +9053,7 @@ fn builtinCall(
|
||||
const builtin_name = tree.tokenSlice(builtin_token);
|
||||
|
||||
// We handle the different builtins manually because they have different semantics depending
|
||||
// on the function. For example, `@as` and others participate in result location semantics,
|
||||
// and `@cImport` creates a special scope that collects a .c source code text buffer.
|
||||
// on the function. For example, `@as` and others participate in result location semantics.
|
||||
// Also, some builtins have a variable number of parameters.
|
||||
|
||||
const info = BuiltinFn.list.get(builtin_name) orelse {
|
||||
@@ -9175,7 +9172,6 @@ fn builtinCall(
|
||||
.bit_cast => return bitCast( gz, scope, ri, node, params[0]),
|
||||
.TypeOf => return typeOf( gz, scope, ri, node, params),
|
||||
.union_init => return unionInit(gz, scope, ri, node, params),
|
||||
.c_import => return cImport( gz, scope, node, params[0]),
|
||||
.min => return minMax( gz, scope, ri, node, params, .min),
|
||||
.max => return minMax( gz, scope, ri, node, params, .max),
|
||||
// zig fmt: on
|
||||
@@ -9484,9 +9480,6 @@ fn builtinCall(
|
||||
.bit_offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .bit_offset_of),
|
||||
.offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .offset_of),
|
||||
|
||||
.c_undef => return simpleCBuiltin(gz, scope, ri, node, params[0], .c_undef),
|
||||
.c_include => return simpleCBuiltin(gz, scope, ri, node, params[0], .c_include),
|
||||
|
||||
.cmpxchg_strong => return cmpxchg(gz, scope, ri, node, params, 1),
|
||||
.cmpxchg_weak => return cmpxchg(gz, scope, ri, node, params, 0),
|
||||
// zig fmt: on
|
||||
@@ -9509,17 +9502,6 @@ fn builtinCall(
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.c_define => {
|
||||
if (!gz.c_import) return gz.astgen.failNode(node, "C define valid only inside C import block", .{});
|
||||
const name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[0], .operand_cDefine_macro_name);
|
||||
const value = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1], .operand_cDefine_macro_value);
|
||||
const result = try gz.addExtendedPayload(.c_define, Zir.Inst.BinNode{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.lhs = name,
|
||||
.rhs = value,
|
||||
});
|
||||
return rvalue(gz, ri, result, node);
|
||||
},
|
||||
.splat => {
|
||||
const result_type = try ri.rl.resultTypeForCast(gz, node, builtin_name);
|
||||
const elem_type = try gz.addUnNode(.splat_op_result_ty, result_type, node);
|
||||
@@ -9951,30 +9933,6 @@ fn divBuiltin(
|
||||
return rvalue(gz, ri, result, node);
|
||||
}
|
||||
|
||||
fn simpleCBuiltin(
|
||||
gz: *GenZir,
|
||||
scope: *Scope,
|
||||
ri: ResultInfo,
|
||||
node: Ast.Node.Index,
|
||||
operand_node: Ast.Node.Index,
|
||||
tag: Zir.Inst.Extended,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const name: []const u8 = if (tag == .c_undef) "C undef" else "C include";
|
||||
if (!gz.c_import) return gz.astgen.failNode(node, "{s} valid only inside C import block", .{name});
|
||||
const operand = try comptimeExpr(
|
||||
gz,
|
||||
scope,
|
||||
.{ .rl = .{ .coerced_ty = .slice_const_u8_type } },
|
||||
operand_node,
|
||||
if (tag == .c_undef) .operand_cUndef_macro_name else .operand_cInclude_file_name,
|
||||
);
|
||||
_ = try gz.addExtendedPayload(tag, Zir.Inst.UnNode{
|
||||
.node = gz.nodeIndexToRelative(node),
|
||||
.operand = operand,
|
||||
});
|
||||
return rvalue(gz, ri, .void_value, node);
|
||||
}
|
||||
|
||||
fn offsetOf(
|
||||
gz: *GenZir,
|
||||
scope: *Scope,
|
||||
@@ -10024,35 +9982,6 @@ fn shiftOp(
|
||||
return rvalue(gz, ri, result, node);
|
||||
}
|
||||
|
||||
fn cImport(
|
||||
gz: *GenZir,
|
||||
scope: *Scope,
|
||||
node: Ast.Node.Index,
|
||||
body_node: Ast.Node.Index,
|
||||
) InnerError!Zir.Inst.Ref {
|
||||
const astgen = gz.astgen;
|
||||
const gpa = astgen.gpa;
|
||||
|
||||
if (gz.c_import) return gz.astgen.failNode(node, "cannot nest @cImport", .{});
|
||||
|
||||
var block_scope = gz.makeSubBlock(scope);
|
||||
block_scope.is_comptime = true;
|
||||
block_scope.c_import = true;
|
||||
defer block_scope.unstack();
|
||||
|
||||
const block_inst = try gz.makeBlockInst(.c_import, node);
|
||||
const block_result = try fullBodyExpr(&block_scope, &block_scope.base, .{ .rl = .none }, body_node, .normal);
|
||||
_ = try gz.addUnNode(.ensure_result_used, block_result, node);
|
||||
if (!gz.refIsNoReturn(block_result)) {
|
||||
_ = try block_scope.addBreak(.break_inline, block_inst, .void_value);
|
||||
}
|
||||
try block_scope.setBlockBody(block_inst);
|
||||
// block_scope unstacked now, can add new instructions to gz
|
||||
try gz.instructions.append(gpa, block_inst);
|
||||
|
||||
return block_inst.toRef();
|
||||
}
|
||||
|
||||
fn overflowArithmetic(
|
||||
gz: *GenZir,
|
||||
scope: *Scope,
|
||||
@@ -11339,7 +11268,6 @@ const GenZir = struct {
|
||||
/// This is set to true for a `GenZir` of a `block_inline`, indicating that
|
||||
/// exits from this block should use `break_inline` rather than `break`.
|
||||
is_inline: bool = false,
|
||||
c_import: bool = false,
|
||||
/// The containing decl AST node.
|
||||
decl_node_index: Ast.Node.Index,
|
||||
/// The containing decl line index, absolute.
|
||||
@@ -11427,7 +11355,6 @@ const GenZir = struct {
|
||||
return .{
|
||||
.is_comptime = gz.is_comptime,
|
||||
.is_typeof = gz.is_typeof,
|
||||
.c_import = gz.c_import,
|
||||
.decl_node_index = gz.decl_node_index,
|
||||
.decl_line = gz.decl_line,
|
||||
.parent = scope,
|
||||
|
||||
@@ -842,10 +842,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
|
||||
_ = try astrl.expr(args[2], block, ResultInfo.type_only);
|
||||
return false;
|
||||
},
|
||||
.c_import => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.none);
|
||||
return false;
|
||||
},
|
||||
.min, .max => {
|
||||
for (args) |arg_node| {
|
||||
_ = try astrl.expr(arg_node, block, ResultInfo.none);
|
||||
@@ -907,8 +903,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
|
||||
.error_name,
|
||||
.set_runtime_safety,
|
||||
.Tuple,
|
||||
.c_undef,
|
||||
.c_include,
|
||||
.wasm_memory_size,
|
||||
.splat,
|
||||
.set_float_mode,
|
||||
@@ -986,11 +980,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||
return false;
|
||||
},
|
||||
.c_define => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.none);
|
||||
return false;
|
||||
},
|
||||
.reduce => {
|
||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||
_ = try astrl.expr(args[1], block, ResultInfo.none);
|
||||
|
||||
@@ -20,9 +20,6 @@ pub const Tag = enum {
|
||||
bit_reverse,
|
||||
offset_of,
|
||||
call,
|
||||
c_define,
|
||||
c_import,
|
||||
c_include,
|
||||
clz,
|
||||
cmpxchg_strong,
|
||||
cmpxchg_weak,
|
||||
@@ -30,7 +27,6 @@ pub const Tag = enum {
|
||||
compile_log,
|
||||
const_cast,
|
||||
ctz,
|
||||
c_undef,
|
||||
c_va_arg,
|
||||
c_va_copy,
|
||||
c_va_end,
|
||||
@@ -306,27 +302,6 @@ pub const list = list: {
|
||||
.param_count = 3,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@cDefine",
|
||||
.{
|
||||
.tag = .c_define,
|
||||
.param_count = 2,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@cImport",
|
||||
.{
|
||||
.tag = .c_import,
|
||||
.param_count = 1,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@cInclude",
|
||||
.{
|
||||
.tag = .c_include,
|
||||
.param_count = 1,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@clz",
|
||||
.{
|
||||
@@ -376,13 +351,6 @@ pub const list = list: {
|
||||
.param_count = 1,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@cUndef",
|
||||
.{
|
||||
.tag = .c_undef,
|
||||
.param_count = 1,
|
||||
},
|
||||
},
|
||||
.{
|
||||
"@cVaArg",
|
||||
.{
|
||||
|
||||
@@ -1016,9 +1016,6 @@ pub const Inst = struct {
|
||||
/// Implements the `@max` builtin for 2 args.
|
||||
/// Uses the `pl_node` union field with payload `Bin`
|
||||
max,
|
||||
/// Implements the `@cImport` builtin.
|
||||
/// Uses the `pl_node` union field with payload `Block`.
|
||||
c_import,
|
||||
|
||||
/// Allocates stack local memory.
|
||||
/// Uses the `un_node` union field. The operand is the type of the allocated object.
|
||||
@@ -1297,7 +1294,6 @@ pub const Inst = struct {
|
||||
.memset,
|
||||
.memmove,
|
||||
.min,
|
||||
.c_import,
|
||||
.@"resume",
|
||||
.ret_err_value_code,
|
||||
.extended,
|
||||
@@ -1577,7 +1573,6 @@ pub const Inst = struct {
|
||||
.builtin_call,
|
||||
.max,
|
||||
.min,
|
||||
.c_import,
|
||||
.@"resume",
|
||||
.ret_err_value_code,
|
||||
.@"break",
|
||||
@@ -1857,7 +1852,6 @@ pub const Inst = struct {
|
||||
.memset = .pl_node,
|
||||
.memmove = .pl_node,
|
||||
.min = .pl_node,
|
||||
.c_import = .pl_node,
|
||||
|
||||
.alloc = .un_node,
|
||||
.alloc_mut = .un_node,
|
||||
@@ -2018,12 +2012,6 @@ pub const Inst = struct {
|
||||
/// `small` is unused.
|
||||
round_op_ty,
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
c_undef,
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
c_include,
|
||||
/// `operand` is payload index to `BinNode`.
|
||||
c_define,
|
||||
/// `operand` is payload index to `UnNode`.
|
||||
wasm_memory_size,
|
||||
/// `operand` is payload index to `BinNode`.
|
||||
wasm_memory_grow,
|
||||
@@ -4360,9 +4348,6 @@ fn findTrackableInner(
|
||||
.mul_with_overflow,
|
||||
.shl_with_overflow,
|
||||
.round_op,
|
||||
.c_undef,
|
||||
.c_include,
|
||||
.c_define,
|
||||
.wasm_memory_size,
|
||||
.wasm_memory_grow,
|
||||
.prefetch,
|
||||
@@ -4532,7 +4517,6 @@ fn findTrackableInner(
|
||||
|
||||
.block,
|
||||
.block_inline,
|
||||
.c_import,
|
||||
.typeof_builtin,
|
||||
.loop,
|
||||
=> {
|
||||
|
||||
+6
-103
@@ -172,7 +172,6 @@ verbose_intern_pool: bool,
|
||||
verbose_generic_instances: bool,
|
||||
verbose_llvm_ir: ?[]const u8,
|
||||
verbose_llvm_bc: ?[]const u8,
|
||||
verbose_cimport: bool,
|
||||
verbose_llvm_cpu_features: bool,
|
||||
verbose_link: bool,
|
||||
link_depfile: ?[]const u8,
|
||||
@@ -1681,7 +1680,6 @@ pub const CreateOptions = struct {
|
||||
verbose_llvm_ir: ?[]const u8 = null,
|
||||
verbose_llvm_bc: ?[]const u8 = null,
|
||||
link_depfile: ?[]const u8 = null,
|
||||
verbose_cimport: bool = false,
|
||||
verbose_llvm_cpu_features: bool = false,
|
||||
debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,
|
||||
debug_compile_errors: bool = false,
|
||||
@@ -2254,7 +2252,6 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
|
||||
.verbose_llvm_ir = options.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = options.verbose_llvm_bc,
|
||||
.link_depfile = options.link_depfile,
|
||||
.verbose_cimport = options.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = options.verbose_llvm_cpu_features,
|
||||
.verbose_link = options.verbose_link,
|
||||
.disable_c_depfile = options.disable_c_depfile,
|
||||
@@ -4095,27 +4092,6 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
|
||||
|
||||
try addModuleErrorMsg(zcu, &bundle, error_msg.*, added_any_analysis_error);
|
||||
added_any_analysis_error = true;
|
||||
|
||||
if (zcu.cimport_errors.get(anal_unit)) |errors| {
|
||||
for (errors.getMessages()) |err_msg_index| {
|
||||
const err_msg = errors.getErrorMessage(err_msg_index);
|
||||
try bundle.addRootErrorMessage(.{
|
||||
.msg = try bundle.addString(errors.nullTerminatedString(err_msg.msg)),
|
||||
.src_loc = if (err_msg.src_loc != .none) blk: {
|
||||
const src_loc = errors.getSourceLocation(err_msg.src_loc);
|
||||
break :blk try bundle.addSourceLocation(.{
|
||||
.src_path = try bundle.addString(errors.nullTerminatedString(src_loc.src_path)),
|
||||
.span_start = src_loc.span_start,
|
||||
.span_main = src_loc.span_main,
|
||||
.span_end = src_loc.span_end,
|
||||
.line = src_loc.line,
|
||||
.column = src_loc.column,
|
||||
.source_line = if (src_loc.source_line != 0) try bundle.addString(errors.nullTerminatedString(src_loc.source_line)) else 0,
|
||||
});
|
||||
} else .none,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
try zcu.addDependencyLoopErrors(&bundle);
|
||||
for (zcu.failed_codegen.values()) |error_msg| {
|
||||
@@ -5048,7 +5024,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU
|
||||
.verbose_generic_instances = comp.verbose_intern_pool,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.environ_map = comp.environ_map,
|
||||
}) catch |err| switch (err) {
|
||||
@@ -5100,8 +5075,8 @@ pub fn obtainCObjectCacheManifest(
|
||||
) Cache.Manifest {
|
||||
var man = comp.cache_parent.obtain();
|
||||
|
||||
// Only things that need to be added on top of the base hash, and only things
|
||||
// that apply both to @cImport and compiling C objects. No linking stuff here!
|
||||
// Only things that need to be added on top of the base hash, and only
|
||||
// things that apply to compiling C objects. No linking stuff here!
|
||||
// Also nothing that applies only to compiling .zig code.
|
||||
cache_helpers.addModule(&man.hash, owner_mod);
|
||||
man.hash.addListOfBytes(comp.global_cc_argv);
|
||||
@@ -5126,13 +5101,13 @@ pub fn obtainWin32ResourceCacheManifest(comp: *const Compilation) Cache.Manifest
|
||||
return man;
|
||||
}
|
||||
|
||||
pub const CImportResult = struct {
|
||||
pub const TranslateCResult = struct {
|
||||
// Only valid if `errors` is not empty
|
||||
digest: [Cache.bin_digest_len]u8,
|
||||
cache_hit: bool,
|
||||
errors: std.zig.ErrorBundle,
|
||||
|
||||
pub fn deinit(result: *CImportResult, gpa: mem.Allocator) void {
|
||||
pub fn deinit(result: *TranslateCResult, gpa: mem.Allocator) void {
|
||||
result.errors.deinit(gpa);
|
||||
}
|
||||
};
|
||||
@@ -5142,15 +5117,12 @@ pub fn translateC(
|
||||
arena: Allocator,
|
||||
man: *Cache.Manifest,
|
||||
ext: FileExt,
|
||||
source: union(enum) {
|
||||
path: []const u8,
|
||||
c_src: []const u8,
|
||||
},
|
||||
source_path: []const u8,
|
||||
translated_basename: []const u8,
|
||||
owner_mod: *Package.Module,
|
||||
prog_node: std.Progress.Node,
|
||||
environ_map: *const std.process.Environ.Map,
|
||||
) !CImportResult {
|
||||
) !TranslateCResult {
|
||||
dev.check(.translate_c_command);
|
||||
|
||||
const gpa = comp.gpa;
|
||||
@@ -5166,17 +5138,6 @@ pub fn translateC(
|
||||
defer cache_tmp_dir.close(io);
|
||||
|
||||
const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename });
|
||||
const source_path = switch (source) {
|
||||
.c_src => |c_src| path: {
|
||||
const cimport_basename = "cimport.h";
|
||||
const out_h_sub_path = tmp_sub_path ++ fs.path.sep_str ++ cimport_basename;
|
||||
const out_h_path = try comp.dirs.local_cache.join(arena, &.{out_h_sub_path});
|
||||
if (comp.verbose_cimport) log.info("writing C import source to {s}", .{out_h_path});
|
||||
try cache_dir.writeFile(io, .{ .sub_path = out_h_sub_path, .data = c_src });
|
||||
break :path out_h_path;
|
||||
},
|
||||
.path => |p| p,
|
||||
};
|
||||
|
||||
const out_dep_path: ?[]const u8 = blk: {
|
||||
if (comp.disable_c_depfile) break :blk null;
|
||||
@@ -5219,15 +5180,12 @@ pub fn translateC(
|
||||
try argv.appendSlice(comp.global_cc_argv);
|
||||
try argv.appendSlice(owner_mod.cc_argv);
|
||||
try argv.appendSlice(&.{ source_path, "-o", translated_path });
|
||||
if (comp.verbose_cimport) try dumpArgv(io, argv.items);
|
||||
}
|
||||
|
||||
var stdout: []u8 = undefined;
|
||||
try @import("main.zig").translateC(gpa, arena, io, argv.items, environ_map, prog_node, comp.thread_limit, &stdout);
|
||||
|
||||
if (out_dep_path) |dep_file_path| add_deps: {
|
||||
if (comp.verbose_cimport) log.info("processing dep file at {s}", .{dep_file_path});
|
||||
|
||||
const dep_basename = fs.path.basename(dep_file_path);
|
||||
// Add the files depended on to the cache system, if a dep file was emitted
|
||||
man.addDepFilePost(cache_tmp_dir, dep_basename) catch |err| switch (err) {
|
||||
@@ -5274,7 +5232,6 @@ pub fn translateC(
|
||||
const hex_digest = Cache.binToHex(bin_digest);
|
||||
const o_sub_path = "o" ++ fs.path.sep_str ++ hex_digest;
|
||||
|
||||
if (comp.verbose_cimport) log.info("renaming {s} to {s}", .{ tmp_sub_path, o_sub_path });
|
||||
try renameTmpIntoCache(io, comp.dirs.local_cache, tmp_sub_path, o_sub_path);
|
||||
|
||||
return .{
|
||||
@@ -5284,58 +5241,6 @@ pub fn translateC(
|
||||
};
|
||||
}
|
||||
|
||||
/// Caller owns returned memory.
|
||||
pub fn cImport(
|
||||
comp: *Compilation,
|
||||
c_src: []const u8,
|
||||
owner_mod: *Package.Module,
|
||||
prog_node: std.Progress.Node,
|
||||
) !CImportResult {
|
||||
dev.check(.translate_c_command);
|
||||
|
||||
const translated_basename = "cimport.zig";
|
||||
|
||||
var man = comp.obtainCObjectCacheManifest(owner_mod);
|
||||
defer man.deinit();
|
||||
|
||||
man.hash.add(@as(u16, 0x7dd9)); // Random number to distinguish c-import from compiling C objects
|
||||
man.hash.addBytes(c_src);
|
||||
|
||||
const result: CImportResult = if (try man.hit()) .{
|
||||
.digest = man.finalBin(),
|
||||
.cache_hit = true,
|
||||
.errors = ErrorBundle.empty,
|
||||
} else result: {
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
break :result try translateC(
|
||||
comp,
|
||||
arena,
|
||||
&man,
|
||||
.c,
|
||||
.{ .c_src = c_src },
|
||||
translated_basename,
|
||||
owner_mod,
|
||||
prog_node,
|
||||
comp.environ_map,
|
||||
);
|
||||
};
|
||||
|
||||
if (result.errors.errorMessageCount() == 0 and man.have_exclusive_lock) {
|
||||
// Write the updated manifest. This is a no-op if the manifest is not dirty. Note that it is
|
||||
// possible we had a hit and the manifest is dirty, for example if the file mtime changed but
|
||||
// the contents were the same, we hit the cache but the manifest is dirty and we need to update
|
||||
// it to prevent doing a full file content comparison the next time around.
|
||||
man.writeManifest() catch |err| {
|
||||
log.warn("failed to write cache manifest for C import: {s}", .{@errorName(err)});
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn workerUpdateCObject(
|
||||
comp: *Compilation,
|
||||
c_object: *CObject,
|
||||
@@ -7492,7 +7397,6 @@ fn buildOutputFromZig(
|
||||
.verbose_generic_instances = comp.verbose_intern_pool,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.skip_linker_dependencies = true,
|
||||
@@ -7630,7 +7534,6 @@ pub fn build_crt_file(
|
||||
.verbose_generic_instances = comp.verbose_generic_instances,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.skip_linker_dependencies = true,
|
||||
|
||||
-186
@@ -385,8 +385,6 @@ pub const Block = struct {
|
||||
/// What mode to generate float operations in, set by @setFloatMode
|
||||
float_mode: std.builtin.FloatMode = .strict,
|
||||
|
||||
c_import_buf: ?*std.array_list.Managed(u8) = null,
|
||||
|
||||
/// If not `null`, this boolean is set when a `dbg_var_ptr`, `dbg_var_val`, or `dbg_arg_inline`.
|
||||
/// instruction is emitted. It signals that the innermost lexically
|
||||
/// enclosing `block`/`block_inline` should be translated into a real AIR
|
||||
@@ -526,7 +524,6 @@ pub const Block = struct {
|
||||
.runtime_index = parent.runtime_index,
|
||||
.want_safety = parent.want_safety,
|
||||
.float_mode = parent.float_mode,
|
||||
.c_import_buf = parent.c_import_buf,
|
||||
.error_return_trace_index = parent.error_return_trace_index,
|
||||
.need_debug_scope = parent.need_debug_scope,
|
||||
.src_base_inst = parent.src_base_inst,
|
||||
@@ -1189,7 +1186,6 @@ fn analyzeBodyInner(
|
||||
.bool_not => try sema.zirBoolNot(block, inst),
|
||||
.bool_br_and => try sema.zirBoolBr(block, inst, false),
|
||||
.bool_br_or => try sema.zirBoolBr(block, inst, true),
|
||||
.c_import => try sema.zirCImport(block, inst),
|
||||
.call => try sema.zirCall(block, inst, .direct),
|
||||
.field_call => try sema.zirCall(block, inst, .field),
|
||||
.cmp_lt => try sema.zirCmp(block, inst, .lt),
|
||||
@@ -1414,9 +1410,6 @@ fn analyzeBodyInner(
|
||||
.sub_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
||||
.mul_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
||||
.shl_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
||||
.c_undef => try sema.zirCUndef( block, extended),
|
||||
.c_include => try sema.zirCInclude( block, extended),
|
||||
.c_define => try sema.zirCDefine( block, extended),
|
||||
.wasm_memory_size => try sema.zirWasmMemorySize( block, extended),
|
||||
.wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended),
|
||||
.prefetch => try sema.zirPrefetch( block, extended),
|
||||
@@ -5212,136 +5205,6 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
return sema.resolveAnalyzedBlock(parent_block, src, &child_block, merges, false);
|
||||
}
|
||||
|
||||
fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const comp = zcu.comp;
|
||||
const gpa = comp.gpa;
|
||||
const io = comp.io;
|
||||
|
||||
const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
|
||||
const src = parent_block.nodeOffset(pl_node.src_node);
|
||||
const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index);
|
||||
const body = sema.code.bodySlice(extra.end, extra.data.body_len);
|
||||
|
||||
var c_import_buf = std.array_list.Managed(u8).init(gpa);
|
||||
defer c_import_buf.deinit();
|
||||
|
||||
var child_block: Block = .{
|
||||
.parent = parent_block,
|
||||
.sema = sema,
|
||||
.namespace = parent_block.namespace,
|
||||
.instructions = .empty,
|
||||
.inlining = parent_block.inlining,
|
||||
.comptime_reason = .{ .reason = .{
|
||||
.src = src,
|
||||
.r = .{ .simple = .operand_cImport },
|
||||
} },
|
||||
.c_import_buf = &c_import_buf,
|
||||
.runtime_cond = parent_block.runtime_cond,
|
||||
.runtime_loop = parent_block.runtime_loop,
|
||||
.runtime_index = parent_block.runtime_index,
|
||||
.src_base_inst = parent_block.src_base_inst,
|
||||
.type_name_ctx = parent_block.type_name_ctx,
|
||||
};
|
||||
defer child_block.instructions.deinit(gpa);
|
||||
|
||||
_ = try sema.analyzeInlineBody(&child_block, body, inst);
|
||||
|
||||
const prog_node = zcu.cur_sema_prog_node.start("@cImport", 0);
|
||||
defer prog_node.end();
|
||||
|
||||
var c_import_res = comp.cImport(c_import_buf.items, parent_block.ownerModule(), prog_node) catch |err|
|
||||
return sema.fail(&child_block, src, "C import failed: {t}", .{err});
|
||||
defer c_import_res.deinit(gpa);
|
||||
|
||||
if (c_import_res.errors.errorMessageCount() != 0) {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(src, "C import failed", .{});
|
||||
errdefer msg.destroy(gpa);
|
||||
|
||||
if (!comp.config.link_libc)
|
||||
try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{});
|
||||
|
||||
const gop = try zcu.cimport_errors.getOrPut(gpa, sema.owner);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = c_import_res.errors;
|
||||
c_import_res.errors = std.zig.ErrorBundle.empty;
|
||||
}
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(&child_block, msg);
|
||||
}
|
||||
const parent_mod = parent_block.ownerModule();
|
||||
const digest = Cache.binToHex(c_import_res.digest);
|
||||
|
||||
const new_file_index = file: {
|
||||
const c_import_zig_path = try comp.arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ digest);
|
||||
const c_import_mod = Package.Module.create(comp.arena, .{
|
||||
.paths = .{
|
||||
.root = try .fromRoot(comp.arena, comp.dirs, .local_cache, c_import_zig_path),
|
||||
.root_src_path = "cimport.zig",
|
||||
},
|
||||
.fully_qualified_name = c_import_zig_path,
|
||||
.cc_argv = parent_mod.cc_argv,
|
||||
.inherited = .{},
|
||||
.global = comp.config,
|
||||
.parent = parent_mod,
|
||||
}) catch |err| switch (err) {
|
||||
error.OutOfMemory => |e| return e,
|
||||
// None of these are possible because we are creating a package with
|
||||
// the exact same configuration as the parent package, which already
|
||||
// passed these checks.
|
||||
error.ValgrindUnsupportedOnTarget => unreachable,
|
||||
error.TargetRequiresSingleThreaded => unreachable,
|
||||
error.BackendRequiresSingleThreaded => unreachable,
|
||||
error.TargetRequiresPic => unreachable,
|
||||
error.PieRequiresPic => unreachable,
|
||||
error.DynamicLinkingRequiresPic => unreachable,
|
||||
error.TargetHasNoRedZone => unreachable,
|
||||
error.StackCheckUnsupportedByTarget => unreachable,
|
||||
error.StackProtectorUnsupportedByTarget => unreachable,
|
||||
error.StackProtectorUnavailableWithoutLibC => unreachable,
|
||||
};
|
||||
const c_import_file_path: Compilation.Path = try c_import_mod.root.join(gpa, comp.dirs, "cimport.zig");
|
||||
errdefer c_import_file_path.deinit(gpa);
|
||||
const c_import_file = try gpa.create(Zcu.File);
|
||||
errdefer gpa.destroy(c_import_file);
|
||||
const c_import_file_index = try zcu.intern_pool.createFile(gpa, io, pt.tid, .{
|
||||
.bin_digest = c_import_file_path.digest(),
|
||||
.file = c_import_file,
|
||||
.root_type = .none,
|
||||
});
|
||||
c_import_file.* = .{
|
||||
.status = .never_loaded,
|
||||
.stat = undefined,
|
||||
.is_builtin = false,
|
||||
.path = c_import_file_path,
|
||||
.source = null,
|
||||
.tree = null,
|
||||
.zir = null,
|
||||
.zoir = null,
|
||||
.mod = c_import_mod,
|
||||
.sub_file_path = "cimport.zig",
|
||||
.module_changed = false,
|
||||
.prev_zir = null,
|
||||
.zoir_invalidated = false,
|
||||
};
|
||||
try zcu.alive_files.putNoClobber(zcu.gpa, c_import_file_index, undefined);
|
||||
break :file c_import_file_index;
|
||||
};
|
||||
pt.updateFile(new_file_index, zcu.fileByIndex(new_file_index)) catch |err|
|
||||
return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
|
||||
|
||||
try pt.ensureFilePopulated(new_file_index);
|
||||
const ty: Type = .fromInterned(zcu.fileRootType(new_file_index));
|
||||
try sema.addTypeReferenceEntry(src, ty);
|
||||
return .fromType(ty);
|
||||
}
|
||||
|
||||
fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
|
||||
const src = parent_block.nodeOffset(inst_data.src_node);
|
||||
@@ -5388,7 +5251,6 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
|
||||
.is_typeof = parent_block.is_typeof,
|
||||
.want_safety = parent_block.want_safety,
|
||||
.float_mode = parent_block.float_mode,
|
||||
.c_import_buf = parent_block.c_import_buf,
|
||||
.runtime_cond = parent_block.runtime_cond,
|
||||
.runtime_loop = parent_block.runtime_loop,
|
||||
.runtime_index = parent_block.runtime_index,
|
||||
@@ -24690,54 +24552,6 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
);
|
||||
}
|
||||
|
||||
fn zirCUndef(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
extended: Zir.Inst.Extended.InstData,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
|
||||
const src = block.builtinCallArgSrc(extra.node, 0);
|
||||
|
||||
const name = try sema.resolveConstString(block, src, extra.operand, .{ .simple = .operand_cUndef_macro_name });
|
||||
try block.c_import_buf.?.print("#undef {s}\n", .{name});
|
||||
return .void_value;
|
||||
}
|
||||
|
||||
fn zirCInclude(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
extended: Zir.Inst.Extended.InstData,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
|
||||
const src = block.builtinCallArgSrc(extra.node, 0);
|
||||
|
||||
const name = try sema.resolveConstString(block, src, extra.operand, .{ .simple = .operand_cInclude_file_name });
|
||||
try block.c_import_buf.?.print("#include <{s}>\n", .{name});
|
||||
return .void_value;
|
||||
}
|
||||
|
||||
fn zirCDefine(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
extended: Zir.Inst.Extended.InstData,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const pt = sema.pt;
|
||||
const zcu = pt.zcu;
|
||||
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
|
||||
const name_src = block.builtinCallArgSrc(extra.node, 0);
|
||||
const val_src = block.builtinCallArgSrc(extra.node, 1);
|
||||
|
||||
const name = try sema.resolveConstString(block, name_src, extra.lhs, .{ .simple = .operand_cDefine_macro_name });
|
||||
const rhs = sema.resolveInst(extra.rhs);
|
||||
if (sema.typeOf(rhs).zigTypeTag(zcu) != .void) {
|
||||
const value = try sema.resolveConstString(block, val_src, extra.rhs, .{ .simple = .operand_cDefine_macro_value });
|
||||
try block.c_import_buf.?.print("#define {s} {s}\n", .{ name, value });
|
||||
} else {
|
||||
try block.c_import_buf.?.print("#define {s}\n", .{name});
|
||||
}
|
||||
return .void_value;
|
||||
}
|
||||
|
||||
fn zirWasmMemorySize(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
//! We do this instead of @cImport because the self-hosted compiler is easier
|
||||
//! to bootstrap if it does not depend on translate-c.
|
||||
|
||||
/// Do not compare directly to .True, use toBool() instead.
|
||||
pub const Bool = enum(c_int) {
|
||||
False,
|
||||
|
||||
@@ -1112,7 +1112,6 @@ fn buildSharedLib(
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.version = version,
|
||||
|
||||
@@ -1257,7 +1257,6 @@ fn buildSharedLib(
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.version = version,
|
||||
|
||||
@@ -271,7 +271,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.skip_linker_dependencies = true,
|
||||
@@ -465,7 +464,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.skip_linker_dependencies = true,
|
||||
|
||||
@@ -296,7 +296,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.skip_linker_dependencies = skip_linker_dependencies,
|
||||
|
||||
@@ -157,7 +157,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.skip_linker_dependencies = true,
|
||||
|
||||
@@ -253,7 +253,6 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
|
||||
.verbose_link = comp.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.c_source_files = &.{
|
||||
|
||||
@@ -755,7 +755,6 @@ fn buildSharedLib(
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.version = version,
|
||||
|
||||
@@ -683,7 +683,6 @@ fn buildSharedLib(
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
.soname = soname,
|
||||
|
||||
+5
-13
@@ -860,7 +860,6 @@ fn buildOutputType(
|
||||
var verbose_llvm_ir: ?[]const u8 = null;
|
||||
var verbose_llvm_bc: ?[]const u8 = null;
|
||||
var link_depfile: ?[]const u8 = null;
|
||||
var verbose_cimport = false;
|
||||
var verbose_llvm_cpu_features = false;
|
||||
var time_report = false;
|
||||
var stack_report = false;
|
||||
@@ -1742,8 +1741,6 @@ fn buildOutputType(
|
||||
verbose_llvm_ir = rest;
|
||||
} else if (mem.cutPrefix(u8, arg, "--verbose-llvm-bc=")) |rest| {
|
||||
verbose_llvm_bc = rest;
|
||||
} else if (mem.eql(u8, arg, "--verbose-cimport")) {
|
||||
verbose_cimport = true;
|
||||
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
||||
verbose_llvm_cpu_features = true;
|
||||
} else if (mem.cutPrefix(u8, arg, "-T")) |rest| {
|
||||
@@ -3650,7 +3647,6 @@ fn buildOutputType(
|
||||
.verbose_llvm_ir = verbose_llvm_ir,
|
||||
.verbose_llvm_bc = verbose_llvm_bc,
|
||||
.link_depfile = link_depfile,
|
||||
.verbose_cimport = verbose_cimport,
|
||||
.verbose_llvm_cpu_features = verbose_llvm_cpu_features,
|
||||
.time_report = time_report,
|
||||
.stack_report = stack_report,
|
||||
@@ -4289,7 +4285,7 @@ fn serve(
|
||||
var arena_instance = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_instance.deinit();
|
||||
const arena = arena_instance.allocator();
|
||||
var output: Compilation.CImportResult = undefined;
|
||||
var output: Compilation.TranslateCResult = undefined;
|
||||
try cmdTranslateC(comp, arena, &output, file_system_inputs, main_progress_node, environ_map);
|
||||
defer output.deinit(gpa);
|
||||
|
||||
@@ -4713,7 +4709,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)
|
||||
fn cmdTranslateC(
|
||||
comp: *Compilation,
|
||||
arena: Allocator,
|
||||
fancy_output: ?*Compilation.CImportResult,
|
||||
fancy_output: ?*Compilation.TranslateCResult,
|
||||
file_system_inputs: ?*std.ArrayList(u8),
|
||||
prog_node: std.Progress.Node,
|
||||
environ_map: *process.Environ.Map,
|
||||
@@ -4735,7 +4731,7 @@ fn cmdTranslateC(
|
||||
Compilation.cache_helpers.hashCSource(&man, c_source_file) catch |err|
|
||||
fatal("unable to process '{s}': {t}", .{ c_source_file.src_path, err });
|
||||
|
||||
const result: Compilation.CImportResult = if (try man.hit()) .{
|
||||
const result: Compilation.TranslateCResult = if (try man.hit()) .{
|
||||
.digest = man.finalBin(),
|
||||
.cache_hit = true,
|
||||
.errors = std.zig.ErrorBundle.empty,
|
||||
@@ -4744,7 +4740,7 @@ fn cmdTranslateC(
|
||||
arena,
|
||||
&man,
|
||||
Compilation.classifyFileExt(c_source_file.src_path),
|
||||
.{ .path = c_source_file.src_path },
|
||||
c_source_file.src_path,
|
||||
translated_basename,
|
||||
comp.root_mod,
|
||||
prog_node,
|
||||
@@ -4976,7 +4972,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
|
||||
var verbose_generic_instances = false;
|
||||
var verbose_llvm_ir: ?[]const u8 = null;
|
||||
var verbose_llvm_bc: ?[]const u8 = null;
|
||||
var verbose_cimport = false;
|
||||
var verbose_llvm_cpu_features = false;
|
||||
var fetch_only = false;
|
||||
var fetch_mode: Package.Fetch.JobQueue.Mode = .needed;
|
||||
@@ -5141,8 +5136,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
|
||||
verbose_llvm_ir = rest;
|
||||
} else if (mem.cutPrefix(u8, arg, "--verbose-llvm-bc=")) |rest| {
|
||||
verbose_llvm_bc = rest;
|
||||
} else if (mem.eql(u8, arg, "--verbose-cimport")) {
|
||||
verbose_cimport = true;
|
||||
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
||||
verbose_llvm_cpu_features = true;
|
||||
} else if (mem.eql(u8, arg, "--color")) {
|
||||
@@ -5542,7 +5535,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
|
||||
.verbose_generic_instances = verbose_generic_instances,
|
||||
.verbose_llvm_ir = verbose_llvm_ir,
|
||||
.verbose_llvm_bc = verbose_llvm_bc,
|
||||
.verbose_cimport = verbose_cimport,
|
||||
.verbose_llvm_cpu_features = verbose_llvm_cpu_features,
|
||||
.cache_mode = .whole,
|
||||
.reference_trace = reference_trace,
|
||||
@@ -5550,7 +5542,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
|
||||
.environ_map = environ_map,
|
||||
}) catch |err| switch (err) {
|
||||
error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
|
||||
else => fatal("failed to create compilation: {s}", .{@errorName(err)}),
|
||||
else => fatal("failed to create compilation: {t}", .{err}),
|
||||
};
|
||||
defer comp.destroy();
|
||||
|
||||
|
||||
@@ -429,7 +429,6 @@ const Writer = struct {
|
||||
.block_inline,
|
||||
.suspend_block,
|
||||
.loop,
|
||||
.c_import,
|
||||
.typeof_builtin,
|
||||
=> try self.writeBlock(stream, inst),
|
||||
|
||||
@@ -555,8 +554,6 @@ const Writer = struct {
|
||||
|
||||
.tuple_decl => try self.writeTupleDecl(stream, extended),
|
||||
|
||||
.c_undef,
|
||||
.c_include,
|
||||
.set_float_mode,
|
||||
.wasm_memory_size,
|
||||
.int_from_error,
|
||||
@@ -579,7 +576,6 @@ const Writer = struct {
|
||||
},
|
||||
|
||||
.builtin_extern,
|
||||
.c_define,
|
||||
.error_cast,
|
||||
.wasm_memory_grow,
|
||||
.prefetch,
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
const b = @cDefine("foo", "1");
|
||||
const c = @cImport({
|
||||
_ = @TypeOf(@cDefine("foo", "1"));
|
||||
});
|
||||
const d = @cImport({
|
||||
_ = @cImport(@cDefine("foo", "1"));
|
||||
});
|
||||
|
||||
// error
|
||||
//
|
||||
// :1:11: error: C define valid only inside C import block
|
||||
// :3:17: error: C define valid only inside C import block
|
||||
// :6:9: error: cannot nest @cImport
|
||||
@@ -1,13 +0,0 @@
|
||||
const c = @cImport({
|
||||
if (foo == 0) {}
|
||||
});
|
||||
extern var foo: i32;
|
||||
export fn entry() void {
|
||||
_ = c;
|
||||
}
|
||||
|
||||
// error
|
||||
//
|
||||
// :2:13: error: unable to evaluate comptime expression
|
||||
// :2:9: note: operation is runtime due to this operand
|
||||
// :1:11: note: operand to '@cImport' is evaluated at comptime
|
||||
@@ -36,9 +36,6 @@
|
||||
.compile_asm = .{
|
||||
.path = "compile_asm",
|
||||
},
|
||||
.issue_794 = .{
|
||||
.path = "issue_794",
|
||||
},
|
||||
.issue_5825 = .{
|
||||
.path = "issue_5825",
|
||||
},
|
||||
@@ -84,9 +81,6 @@
|
||||
.dep_shared_builtin = .{
|
||||
.path = "dep_shared_builtin",
|
||||
},
|
||||
.dep_lazypath = .{
|
||||
.path = "dep_lazypath",
|
||||
},
|
||||
.dirname = .{
|
||||
.path = "dirname",
|
||||
},
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
const optimize: std.builtin.OptimizeMode = .Debug;
|
||||
|
||||
{
|
||||
const write_files = b.addWriteFiles();
|
||||
const generated_main_c = write_files.add("main.c", "");
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = null,
|
||||
.target = b.graph.host,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
exe.root_module.addCSourceFiles(.{
|
||||
.root = generated_main_c.dirname(),
|
||||
.files = &.{"main.c"},
|
||||
});
|
||||
b.step("csourcefiles", "").dependOn(&exe.step);
|
||||
test_step.dependOn(&exe.step);
|
||||
}
|
||||
{
|
||||
const write_files = b.addWriteFiles();
|
||||
const dir = write_files.addCopyDirectory(b.path("inc"), "", .{});
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("inctest.zig"),
|
||||
.target = b.graph.host,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
exe.root_module.addIncludePath(dir);
|
||||
b.step("copydir", "").dependOn(&exe.step);
|
||||
test_step.dependOn(&exe.step);
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
#define foo_value 42
|
||||
@@ -1,8 +0,0 @@
|
||||
const std = @import("std");
|
||||
const c = @cImport({
|
||||
@cInclude("foo.h");
|
||||
});
|
||||
comptime {
|
||||
std.debug.assert(c.foo_value == 42);
|
||||
}
|
||||
pub fn main() void {}
|
||||
@@ -180,12 +180,44 @@ pub fn build(b: *std.Build) void {
|
||||
}
|
||||
}
|
||||
|
||||
const malloc_translation = b.addTranslateC(.{
|
||||
.root_source_file = b.path("include_malloc.h"),
|
||||
.target = target,
|
||||
.optimize = .Debug,
|
||||
.link_libc = true,
|
||||
});
|
||||
const stdlib_translation = b.addTranslateC(.{
|
||||
.root_source_file = b.path("include_stdlib.h"),
|
||||
.target = target,
|
||||
.optimize = .Debug,
|
||||
.link_libc = true,
|
||||
});
|
||||
const string_translation = b.addTranslateC(.{
|
||||
.root_source_file = b.path("include_string.h"),
|
||||
.target = target,
|
||||
.optimize = .Debug,
|
||||
.link_libc = true,
|
||||
});
|
||||
const exe = b.addExecutable(.{
|
||||
.name = t,
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("glibc_runtime_check.zig"),
|
||||
.target = target,
|
||||
.link_libc = true,
|
||||
.imports = &.{
|
||||
.{
|
||||
.name = "malloc.h",
|
||||
.module = malloc_translation.createModule(),
|
||||
},
|
||||
.{
|
||||
.name = "stdlib.h",
|
||||
.module = stdlib_translation.createModule(),
|
||||
},
|
||||
.{
|
||||
.name = "string.h",
|
||||
.module = string_translation.createModule(),
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
// We disable UBSAN for these tests as the libc being tested here is
|
||||
|
||||
@@ -8,17 +8,9 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const c_malloc = @cImport(
|
||||
@cInclude("malloc.h"), // for reallocarray
|
||||
);
|
||||
|
||||
const c_stdlib = @cImport(
|
||||
@cInclude("stdlib.h"), // for atexit
|
||||
);
|
||||
|
||||
const c_string = @cImport(
|
||||
@cInclude("string.h"), // for strlcpy
|
||||
);
|
||||
const c_malloc = @import("malloc.h"); // for reallocarray
|
||||
const c_stdlib = @import("stdlib.h"); // for atexit
|
||||
const c_string = @import("string.h"); // for strlcpy
|
||||
|
||||
// Version of glibc this test is being built to run against
|
||||
const glibc_ver = builtin.os.versionRange().gnuLibCVersion().?;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include <malloc.h>
|
||||
@@ -0,0 +1 @@
|
||||
#include <stdlib.h>
|
||||
@@ -0,0 +1 @@
|
||||
#include <string.h>
|
||||
@@ -1 +0,0 @@
|
||||
#define NUMBER 1234
|
||||
@@ -1,17 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
const test_artifact = b.addTest(.{ .root_module = b.createModule(.{
|
||||
.root_source_file = b.path("main.zig"),
|
||||
.target = b.graph.host,
|
||||
}) });
|
||||
test_artifact.root_module.addIncludePath(b.path("a_directory"));
|
||||
|
||||
// TODO: actually check the output
|
||||
_ = test_artifact.getEmittedBin();
|
||||
|
||||
test_step.dependOn(&test_artifact.step);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
const c = @cImport(@cInclude("foo.h"));
|
||||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
|
||||
test "c import" {
|
||||
try comptime testing.expect(c.NUMBER == 1234);
|
||||
}
|
||||
@@ -108,7 +108,6 @@ const cases = [_]Case{
|
||||
.os_tag = .freestanding,
|
||||
},
|
||||
},
|
||||
.{ .src_path = "issue_12471/main.zig" },
|
||||
.{ .src_path = "guess_number/main.zig" },
|
||||
.{ .src_path = "main_return_error/error_u8.zig" },
|
||||
.{ .src_path = "main_return_error/error_u8_non_zero.zig" },
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
const c = @cImport({
|
||||
@cDefine("FOO", "FOO");
|
||||
@cDefine("BAR", "FOO");
|
||||
|
||||
@cDefine("BAZ", "QUX");
|
||||
@cDefine("QUX", "QUX");
|
||||
});
|
||||
|
||||
pub fn main() u8 {
|
||||
_ = c;
|
||||
return 0;
|
||||
}
|
||||
+1
-14
@@ -185,10 +185,6 @@ fn printOutput(
|
||||
try shell_out.print("-fno-llvm", .{});
|
||||
}
|
||||
}
|
||||
if (code.verbose_cimport) {
|
||||
try build_args.append("--verbose-cimport");
|
||||
try shell_out.print("--verbose-cimport ", .{});
|
||||
}
|
||||
for (code.additional_options) |option| {
|
||||
try build_args.append(option);
|
||||
try shell_out.print("{s} ", .{option});
|
||||
@@ -223,11 +219,7 @@ fn printOutput(
|
||||
}
|
||||
const exec_result = run(arena, io, environ_map, tmp_dir_path, build_args.items) catch
|
||||
fatal("example failed to compile", .{});
|
||||
|
||||
if (code.verbose_cimport) {
|
||||
const escaped_build_stderr = try escapeHtml(arena, exec_result.stderr);
|
||||
try shell_out.writeAll(escaped_build_stderr);
|
||||
}
|
||||
_ = exec_result;
|
||||
|
||||
if (code.target_str) |triple| {
|
||||
if (mem.startsWith(u8, triple, "wasm32") or
|
||||
@@ -853,7 +845,6 @@ const Code = struct {
|
||||
link_libc: bool,
|
||||
link_mode: ?std.builtin.LinkMode,
|
||||
disable_cache: bool,
|
||||
verbose_cimport: bool,
|
||||
just_check_syntax: bool,
|
||||
additional_options: []const []const u8,
|
||||
use_llvm: ?bool,
|
||||
@@ -915,7 +906,6 @@ fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code {
|
||||
var target_str: ?[]const u8 = null;
|
||||
var link_libc = false;
|
||||
var disable_cache = false;
|
||||
var verbose_cimport = false;
|
||||
var use_llvm: ?bool = null;
|
||||
|
||||
while (it.next()) |prefixed_line| {
|
||||
@@ -940,8 +930,6 @@ fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code {
|
||||
link_libc = true;
|
||||
} else if (mem.eql(u8, line, "disable_cache")) {
|
||||
disable_cache = true;
|
||||
} else if (mem.eql(u8, line, "verbose_cimport")) {
|
||||
verbose_cimport = true;
|
||||
} else {
|
||||
fatal("unrecognized manifest line: {s}", .{line});
|
||||
}
|
||||
@@ -956,7 +944,6 @@ fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code {
|
||||
.link_libc = link_libc,
|
||||
.link_mode = link_mode,
|
||||
.disable_cache = disable_cache,
|
||||
.verbose_cimport = verbose_cimport,
|
||||
.just_check_syntax = just_check_syntax,
|
||||
.use_llvm = use_llvm,
|
||||
};
|
||||
|
||||
@@ -249,7 +249,6 @@ const Code = struct {
|
||||
link_libc: bool,
|
||||
link_mode: ?std.builtin.LinkMode,
|
||||
disable_cache: bool,
|
||||
verbose_cimport: bool,
|
||||
additional_options: []const []const u8,
|
||||
|
||||
const Id = union(enum) {
|
||||
@@ -326,7 +325,6 @@ fn walk(arena: Allocator, io: Io, tokenizer: *Tokenizer, out_dir: Dir, w: anytyp
|
||||
var link_libc = false;
|
||||
var link_mode: ?std.builtin.LinkMode = null;
|
||||
var disable_cache = false;
|
||||
var verbose_cimport = false;
|
||||
var additional_options = std.array_list.Managed([]const u8).init(arena);
|
||||
|
||||
const source_token = while (true) {
|
||||
@@ -340,8 +338,6 @@ fn walk(arena: Allocator, io: Io, tokenizer: *Tokenizer, out_dir: Dir, w: anytyp
|
||||
mode = .ReleaseSafe;
|
||||
} else if (mem.eql(u8, end_tag_name, "code_disable_cache")) {
|
||||
disable_cache = true;
|
||||
} else if (mem.eql(u8, end_tag_name, "code_verbose_cimport")) {
|
||||
verbose_cimport = true;
|
||||
} else if (mem.eql(u8, end_tag_name, "code_link_object")) {
|
||||
_ = try eatToken(tokenizer, .separator);
|
||||
const obj_tok = try eatToken(tokenizer, .tag_content);
|
||||
@@ -419,7 +415,6 @@ fn walk(arena: Allocator, io: Io, tokenizer: *Tokenizer, out_dir: Dir, w: anytyp
|
||||
|
||||
if (link_libc) try code.print("// link_libc\n", .{});
|
||||
if (disable_cache) try code.print("// disable_cache\n", .{});
|
||||
if (verbose_cimport) try code.print("// verbose_cimport\n", .{});
|
||||
|
||||
if (link_mode) |m|
|
||||
try code.print("// link_mode={s}\n", .{@tagName(m)});
|
||||
|
||||
Reference in New Issue
Block a user