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."
|
about: "Please use one of the community spaces instead for questions or general discussions."
|
||||||
url: https://ziglang.org/community
|
url: https://ziglang.org/community
|
||||||
- name: C Translation
|
- 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
|
url: https://codeberg.org/ziglang/translate-c
|
||||||
- name: Copilot and Other LLMs
|
- name: Copilot and Other LLMs
|
||||||
about: "Please do not use GitHub Copilot or any other LLM to write an issue."
|
about: "Please do not use GitHub Copilot or any other LLM to write an issue."
|
||||||
|
|||||||
@@ -735,11 +735,6 @@ if(MSVC OR MINGW)
|
|||||||
endif()
|
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
|
set(ZIG_BUILD_ARGS
|
||||||
--zig-lib-dir "${PROJECT_SOURCE_DIR}/lib"
|
--zig-lib-dir "${PROJECT_SOURCE_DIR}/lib"
|
||||||
|
|
||||||
@@ -749,8 +744,6 @@ set(ZIG_BUILD_ARGS
|
|||||||
|
|
||||||
-Denable-llvm
|
-Denable-llvm
|
||||||
"-Dconfig_h=${ZIG_CONFIG_H_OUT}"
|
"-Dconfig_h=${ZIG_CONFIG_H_OUT}"
|
||||||
|
|
||||||
-Dno-langref
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ZIG_EXTRA_BUILD_ARGS "" CACHE STRING "Extra zig build args")
|
set(ZIG_EXTRA_BUILD_ARGS "" CACHE STRING "Extra zig build args")
|
||||||
|
|||||||
@@ -658,38 +658,31 @@ WebAssembly-related.
|
|||||||
|
|
||||||
### Improving Translate-C
|
### Improving Translate-C
|
||||||
|
|
||||||
`translate-c` is a feature provided by Zig that converts C source code into
|
`translate-c` is a feature provided by Zig that converts C source code into Zig
|
||||||
Zig source code. It powers the `zig translate-c` command as well as
|
source code. It powers the `zig translate-c` command, allowing Zig code to not
|
||||||
[@cImport](https://ziglang.org/documentation/master/#cImport), allowing Zig
|
only take advantage of function prototypes defined in C header files, but also
|
||||||
code to not only take advantage of function prototypes defined in .h files,
|
`static inline` functions written in C, and even some macros.
|
||||||
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
|
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,
|
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
|
generating Zig AST, and finally using the mechanisms of `zig fmt` to render the
|
||||||
Zig AST to a file.
|
Zig AST to a file.
|
||||||
|
|
||||||
However, C translation is in a transitional period right now. It used to be
|
However, it is now based on [arocc](https://github.com/Vexu/arocc/), a
|
||||||
based on Clang, but is now based on Aro:
|
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)
|
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
|
||||||
Test coverage as well as bug reports have been moved to this repository:
|
translation in one's build.zig script.
|
||||||
|
|
||||||
[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`.
|
|
||||||
|
|
||||||
Please see the readme of the translate-c project for how to contribute. Once an
|
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
|
issue is resolved (and test coverage added) there, the changes can be
|
||||||
immediately backported to the zig compiler.
|
immediately backported to the zig compiler.
|
||||||
|
|
||||||
Once we fix the problems people are facing from this transition from Clang to
|
However, in the future, this build step will be removed in favor of explicit
|
||||||
Aro, we can move on to enhancing the translate-c package such that `@cImport`
|
dependency on the translate-c package via build system / package manager. At
|
||||||
becomes redundant and can therefore be eliminated from the language.
|
that point, Zig will stop vendoring arocc.
|
||||||
|
|
||||||
### Autodoc
|
### Autodoc
|
||||||
|
|
||||||
|
|||||||
+2
-163
@@ -1032,9 +1032,8 @@
|
|||||||
{#header_close#}
|
{#header_close#}
|
||||||
|
|
||||||
{#header_open|Local Variables#}
|
{#header_open|Local Variables#}
|
||||||
<p>
|
<p>Local variables occur inside {#link|Functions#}, {#link|comptime#}
|
||||||
Local variables occur inside {#link|Functions#}, {#link|comptime#} blocks, and {#link|@cImport#} blocks.
|
blocks, and labeled {#link|Blocks#}.</p>
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
When a local variable is {#syntax#}const{#endsyntax#}, it means that after initialization, the variable's
|
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
|
value will not change. If the initialization value of a {#syntax#}const{#endsyntax#} variable is
|
||||||
@@ -4573,62 +4572,6 @@ comptime {
|
|||||||
|
|
||||||
{#header_close#}
|
{#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#}
|
{#header_open|@clz#}
|
||||||
<pre>{#syntax#}@clz(operand: anytype) anytype{#endsyntax#}</pre>
|
<pre>{#syntax#}@clz(operand: anytype) anytype{#endsyntax#}</pre>
|
||||||
<p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p>
|
<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#}
|
{#see_also|@clz|@popCount#}
|
||||||
{#header_close#}
|
{#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#}
|
{#header_open|@cVaArg#}
|
||||||
<pre>{#syntax#}@cVaArg(operand: *std.builtin.VaList, comptime T: type) T{#endsyntax#}</pre>
|
<pre>{#syntax#}@cVaArg(operand: *std.builtin.VaList, comptime T: type) T{#endsyntax#}</pre>
|
||||||
<p>
|
<p>
|
||||||
@@ -6784,35 +6715,6 @@ const builtin = @import("builtin");
|
|||||||
</p>
|
</p>
|
||||||
{#see_also|Primitive Types#}
|
{#see_also|Primitive Types#}
|
||||||
{#header_close#}
|
{#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#}
|
{#header_open|C Translation CLI#}
|
||||||
<p>
|
<p>
|
||||||
@@ -6872,42 +6774,8 @@ $ zig translate-c -cflags -fshort-enums -- varycflags.h|grep -B1 do_something
|
|||||||
pub const enum_FOO = u8;
|
pub const enum_FOO = u8;
|
||||||
pub extern fn do_something(foo: enum_FOO) c_int;{#end_shell_samp#}
|
pub extern fn do_something(foo: enum_FOO) c_int;{#end_shell_samp#}
|
||||||
{#header_close#}
|
{#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#}
|
{#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#}
|
{#header_open|Translation failures#}
|
||||||
<p>
|
<p>
|
||||||
Some C constructs cannot be translated to Zig - for example, <em>goto</em>,
|
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>
|
</p>
|
||||||
{#see_also|opaque|extern|@compileError#}
|
{#see_also|opaque|extern|@compileError#}
|
||||||
{#header_close#}
|
{#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#}
|
{#header_open|C Pointers#}
|
||||||
<p>
|
<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
|
// test
|
||||||
// link_libc
|
// 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..];
|
builder.verbose_llvm_ir = arg["--verbose-llvm-ir=".len..];
|
||||||
} else if (mem.startsWith(u8, arg, "--verbose-llvm-bc=")) {
|
} else if (mem.startsWith(u8, arg, "--verbose-llvm-bc=")) {
|
||||||
builder.verbose_llvm_bc = arg["--verbose-llvm-bc=".len..];
|
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")) {
|
} else if (mem.eql(u8, arg, "--verbose-cc")) {
|
||||||
builder.verbose_cc = true;
|
builder.verbose_cc = true;
|
||||||
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ verbose_cc: bool,
|
|||||||
verbose_air: bool,
|
verbose_air: bool,
|
||||||
verbose_llvm_ir: ?[]const u8,
|
verbose_llvm_ir: ?[]const u8,
|
||||||
verbose_llvm_bc: ?[]const u8,
|
verbose_llvm_bc: ?[]const u8,
|
||||||
verbose_cimport: bool,
|
|
||||||
verbose_llvm_cpu_features: bool,
|
verbose_llvm_cpu_features: bool,
|
||||||
reference_trace: ?u32 = null,
|
reference_trace: ?u32 = null,
|
||||||
invalid_user_input: bool,
|
invalid_user_input: bool,
|
||||||
@@ -278,7 +277,6 @@ pub fn create(
|
|||||||
.verbose_air = false,
|
.verbose_air = false,
|
||||||
.verbose_llvm_ir = null,
|
.verbose_llvm_ir = null,
|
||||||
.verbose_llvm_bc = null,
|
.verbose_llvm_bc = null,
|
||||||
.verbose_cimport = false,
|
|
||||||
.verbose_llvm_cpu_features = false,
|
.verbose_llvm_cpu_features = false,
|
||||||
.invalid_user_input = false,
|
.invalid_user_input = false,
|
||||||
.allocator = arena,
|
.allocator = arena,
|
||||||
@@ -377,7 +375,6 @@ fn createChildOnly(
|
|||||||
.verbose_air = parent.verbose_air,
|
.verbose_air = parent.verbose_air,
|
||||||
.verbose_llvm_ir = parent.verbose_llvm_ir,
|
.verbose_llvm_ir = parent.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = parent.verbose_llvm_bc,
|
.verbose_llvm_bc = parent.verbose_llvm_bc,
|
||||||
.verbose_cimport = parent.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features,
|
||||||
.reference_trace = parent.reference_trace,
|
.reference_trace = parent.reference_trace,
|
||||||
.invalid_user_input = false,
|
.invalid_user_input = false,
|
||||||
|
|||||||
@@ -1393,7 +1393,6 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 {
|
|||||||
try zig_args.append("--debug-incremental");
|
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_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_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}));
|
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_branchHint,
|
||||||
operand_setRuntimeSafety,
|
operand_setRuntimeSafety,
|
||||||
operand_embedFile,
|
operand_embedFile,
|
||||||
operand_cImport,
|
|
||||||
operand_cDefine_macro_name,
|
|
||||||
operand_cDefine_macro_value,
|
|
||||||
operand_cInclude_file_name,
|
|
||||||
operand_cUndef_macro_name,
|
|
||||||
operand_shuffle_mask,
|
operand_shuffle_mask,
|
||||||
operand_atomicRmw_operation,
|
operand_atomicRmw_operation,
|
||||||
operand_reduce_operation,
|
operand_reduce_operation,
|
||||||
@@ -891,11 +886,6 @@ pub const SimpleComptimeReason = enum(u32) {
|
|||||||
.operand_branchHint => "operand to '@branchHint' must be comptime-known",
|
.operand_branchHint => "operand to '@branchHint' must be comptime-known",
|
||||||
.operand_setRuntimeSafety => "operand to '@setRuntimeSafety' must be comptime-known",
|
.operand_setRuntimeSafety => "operand to '@setRuntimeSafety' must be comptime-known",
|
||||||
.operand_embedFile => "operand to '@embedFile' 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_shuffle_mask => "'@shuffle' mask must be comptime-known",
|
||||||
.operand_atomicRmw_operation => "'@atomicRmw' operation must be comptime-known",
|
.operand_atomicRmw_operation => "'@atomicRmw' operation must be comptime-known",
|
||||||
.operand_reduce_operation => "'@reduce' 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,
|
.mul_add,
|
||||||
.max,
|
.max,
|
||||||
.min,
|
.min,
|
||||||
.c_import,
|
|
||||||
.@"resume",
|
.@"resume",
|
||||||
.ret_err_value_code,
|
.ret_err_value_code,
|
||||||
.ret_ptr,
|
.ret_ptr,
|
||||||
@@ -8955,7 +8954,6 @@ fn typeOf(
|
|||||||
var typeof_scope = gz.makeSubBlock(scope);
|
var typeof_scope = gz.makeSubBlock(scope);
|
||||||
typeof_scope.is_comptime = false;
|
typeof_scope.is_comptime = false;
|
||||||
typeof_scope.is_typeof = true;
|
typeof_scope.is_typeof = true;
|
||||||
typeof_scope.c_import = false;
|
|
||||||
defer typeof_scope.unstack();
|
defer typeof_scope.unstack();
|
||||||
|
|
||||||
const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, args[0], node);
|
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);
|
const builtin_name = tree.tokenSlice(builtin_token);
|
||||||
|
|
||||||
// We handle the different builtins manually because they have different semantics depending
|
// 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,
|
// 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.
|
|
||||||
// Also, some builtins have a variable number of parameters.
|
// Also, some builtins have a variable number of parameters.
|
||||||
|
|
||||||
const info = BuiltinFn.list.get(builtin_name) orelse {
|
const info = BuiltinFn.list.get(builtin_name) orelse {
|
||||||
@@ -9175,7 +9172,6 @@ fn builtinCall(
|
|||||||
.bit_cast => return bitCast( gz, scope, ri, node, params[0]),
|
.bit_cast => return bitCast( gz, scope, ri, node, params[0]),
|
||||||
.TypeOf => return typeOf( gz, scope, ri, node, params),
|
.TypeOf => return typeOf( gz, scope, ri, node, params),
|
||||||
.union_init => return unionInit(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),
|
.min => return minMax( gz, scope, ri, node, params, .min),
|
||||||
.max => return minMax( gz, scope, ri, node, params, .max),
|
.max => return minMax( gz, scope, ri, node, params, .max),
|
||||||
// zig fmt: on
|
// 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),
|
.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),
|
.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_strong => return cmpxchg(gz, scope, ri, node, params, 1),
|
||||||
.cmpxchg_weak => return cmpxchg(gz, scope, ri, node, params, 0),
|
.cmpxchg_weak => return cmpxchg(gz, scope, ri, node, params, 0),
|
||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
@@ -9509,17 +9502,6 @@ fn builtinCall(
|
|||||||
});
|
});
|
||||||
return rvalue(gz, ri, result, node);
|
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 => {
|
.splat => {
|
||||||
const result_type = try ri.rl.resultTypeForCast(gz, node, builtin_name);
|
const result_type = try ri.rl.resultTypeForCast(gz, node, builtin_name);
|
||||||
const elem_type = try gz.addUnNode(.splat_op_result_ty, result_type, node);
|
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);
|
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(
|
fn offsetOf(
|
||||||
gz: *GenZir,
|
gz: *GenZir,
|
||||||
scope: *Scope,
|
scope: *Scope,
|
||||||
@@ -10024,35 +9982,6 @@ fn shiftOp(
|
|||||||
return rvalue(gz, ri, result, node);
|
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(
|
fn overflowArithmetic(
|
||||||
gz: *GenZir,
|
gz: *GenZir,
|
||||||
scope: *Scope,
|
scope: *Scope,
|
||||||
@@ -11339,7 +11268,6 @@ const GenZir = struct {
|
|||||||
/// This is set to true for a `GenZir` of a `block_inline`, indicating that
|
/// 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`.
|
/// exits from this block should use `break_inline` rather than `break`.
|
||||||
is_inline: bool = false,
|
is_inline: bool = false,
|
||||||
c_import: bool = false,
|
|
||||||
/// The containing decl AST node.
|
/// The containing decl AST node.
|
||||||
decl_node_index: Ast.Node.Index,
|
decl_node_index: Ast.Node.Index,
|
||||||
/// The containing decl line index, absolute.
|
/// The containing decl line index, absolute.
|
||||||
@@ -11427,7 +11355,6 @@ const GenZir = struct {
|
|||||||
return .{
|
return .{
|
||||||
.is_comptime = gz.is_comptime,
|
.is_comptime = gz.is_comptime,
|
||||||
.is_typeof = gz.is_typeof,
|
.is_typeof = gz.is_typeof,
|
||||||
.c_import = gz.c_import,
|
|
||||||
.decl_node_index = gz.decl_node_index,
|
.decl_node_index = gz.decl_node_index,
|
||||||
.decl_line = gz.decl_line,
|
.decl_line = gz.decl_line,
|
||||||
.parent = scope,
|
.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);
|
_ = try astrl.expr(args[2], block, ResultInfo.type_only);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
.c_import => {
|
|
||||||
_ = try astrl.expr(args[0], block, ResultInfo.none);
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
.min, .max => {
|
.min, .max => {
|
||||||
for (args) |arg_node| {
|
for (args) |arg_node| {
|
||||||
_ = try astrl.expr(arg_node, block, ResultInfo.none);
|
_ = try astrl.expr(arg_node, block, ResultInfo.none);
|
||||||
@@ -907,8 +903,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
|
|||||||
.error_name,
|
.error_name,
|
||||||
.set_runtime_safety,
|
.set_runtime_safety,
|
||||||
.Tuple,
|
.Tuple,
|
||||||
.c_undef,
|
|
||||||
.c_include,
|
|
||||||
.wasm_memory_size,
|
.wasm_memory_size,
|
||||||
.splat,
|
.splat,
|
||||||
.set_float_mode,
|
.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);
|
_ = try astrl.expr(args[1], block, ResultInfo.type_only);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
.c_define => {
|
|
||||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
|
||||||
_ = try astrl.expr(args[1], block, ResultInfo.none);
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
.reduce => {
|
.reduce => {
|
||||||
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
_ = try astrl.expr(args[0], block, ResultInfo.type_only);
|
||||||
_ = try astrl.expr(args[1], block, ResultInfo.none);
|
_ = try astrl.expr(args[1], block, ResultInfo.none);
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ pub const Tag = enum {
|
|||||||
bit_reverse,
|
bit_reverse,
|
||||||
offset_of,
|
offset_of,
|
||||||
call,
|
call,
|
||||||
c_define,
|
|
||||||
c_import,
|
|
||||||
c_include,
|
|
||||||
clz,
|
clz,
|
||||||
cmpxchg_strong,
|
cmpxchg_strong,
|
||||||
cmpxchg_weak,
|
cmpxchg_weak,
|
||||||
@@ -30,7 +27,6 @@ pub const Tag = enum {
|
|||||||
compile_log,
|
compile_log,
|
||||||
const_cast,
|
const_cast,
|
||||||
ctz,
|
ctz,
|
||||||
c_undef,
|
|
||||||
c_va_arg,
|
c_va_arg,
|
||||||
c_va_copy,
|
c_va_copy,
|
||||||
c_va_end,
|
c_va_end,
|
||||||
@@ -306,27 +302,6 @@ pub const list = list: {
|
|||||||
.param_count = 3,
|
.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",
|
"@clz",
|
||||||
.{
|
.{
|
||||||
@@ -376,13 +351,6 @@ pub const list = list: {
|
|||||||
.param_count = 1,
|
.param_count = 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.{
|
|
||||||
"@cUndef",
|
|
||||||
.{
|
|
||||||
.tag = .c_undef,
|
|
||||||
.param_count = 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.{
|
.{
|
||||||
"@cVaArg",
|
"@cVaArg",
|
||||||
.{
|
.{
|
||||||
|
|||||||
@@ -1016,9 +1016,6 @@ pub const Inst = struct {
|
|||||||
/// Implements the `@max` builtin for 2 args.
|
/// Implements the `@max` builtin for 2 args.
|
||||||
/// Uses the `pl_node` union field with payload `Bin`
|
/// Uses the `pl_node` union field with payload `Bin`
|
||||||
max,
|
max,
|
||||||
/// Implements the `@cImport` builtin.
|
|
||||||
/// Uses the `pl_node` union field with payload `Block`.
|
|
||||||
c_import,
|
|
||||||
|
|
||||||
/// Allocates stack local memory.
|
/// Allocates stack local memory.
|
||||||
/// Uses the `un_node` union field. The operand is the type of the allocated object.
|
/// Uses the `un_node` union field. The operand is the type of the allocated object.
|
||||||
@@ -1297,7 +1294,6 @@ pub const Inst = struct {
|
|||||||
.memset,
|
.memset,
|
||||||
.memmove,
|
.memmove,
|
||||||
.min,
|
.min,
|
||||||
.c_import,
|
|
||||||
.@"resume",
|
.@"resume",
|
||||||
.ret_err_value_code,
|
.ret_err_value_code,
|
||||||
.extended,
|
.extended,
|
||||||
@@ -1577,7 +1573,6 @@ pub const Inst = struct {
|
|||||||
.builtin_call,
|
.builtin_call,
|
||||||
.max,
|
.max,
|
||||||
.min,
|
.min,
|
||||||
.c_import,
|
|
||||||
.@"resume",
|
.@"resume",
|
||||||
.ret_err_value_code,
|
.ret_err_value_code,
|
||||||
.@"break",
|
.@"break",
|
||||||
@@ -1857,7 +1852,6 @@ pub const Inst = struct {
|
|||||||
.memset = .pl_node,
|
.memset = .pl_node,
|
||||||
.memmove = .pl_node,
|
.memmove = .pl_node,
|
||||||
.min = .pl_node,
|
.min = .pl_node,
|
||||||
.c_import = .pl_node,
|
|
||||||
|
|
||||||
.alloc = .un_node,
|
.alloc = .un_node,
|
||||||
.alloc_mut = .un_node,
|
.alloc_mut = .un_node,
|
||||||
@@ -2018,12 +2012,6 @@ pub const Inst = struct {
|
|||||||
/// `small` is unused.
|
/// `small` is unused.
|
||||||
round_op_ty,
|
round_op_ty,
|
||||||
/// `operand` is payload index to `UnNode`.
|
/// `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,
|
wasm_memory_size,
|
||||||
/// `operand` is payload index to `BinNode`.
|
/// `operand` is payload index to `BinNode`.
|
||||||
wasm_memory_grow,
|
wasm_memory_grow,
|
||||||
@@ -4360,9 +4348,6 @@ fn findTrackableInner(
|
|||||||
.mul_with_overflow,
|
.mul_with_overflow,
|
||||||
.shl_with_overflow,
|
.shl_with_overflow,
|
||||||
.round_op,
|
.round_op,
|
||||||
.c_undef,
|
|
||||||
.c_include,
|
|
||||||
.c_define,
|
|
||||||
.wasm_memory_size,
|
.wasm_memory_size,
|
||||||
.wasm_memory_grow,
|
.wasm_memory_grow,
|
||||||
.prefetch,
|
.prefetch,
|
||||||
@@ -4532,7 +4517,6 @@ fn findTrackableInner(
|
|||||||
|
|
||||||
.block,
|
.block,
|
||||||
.block_inline,
|
.block_inline,
|
||||||
.c_import,
|
|
||||||
.typeof_builtin,
|
.typeof_builtin,
|
||||||
.loop,
|
.loop,
|
||||||
=> {
|
=> {
|
||||||
|
|||||||
+6
-103
@@ -172,7 +172,6 @@ verbose_intern_pool: bool,
|
|||||||
verbose_generic_instances: bool,
|
verbose_generic_instances: bool,
|
||||||
verbose_llvm_ir: ?[]const u8,
|
verbose_llvm_ir: ?[]const u8,
|
||||||
verbose_llvm_bc: ?[]const u8,
|
verbose_llvm_bc: ?[]const u8,
|
||||||
verbose_cimport: bool,
|
|
||||||
verbose_llvm_cpu_features: bool,
|
verbose_llvm_cpu_features: bool,
|
||||||
verbose_link: bool,
|
verbose_link: bool,
|
||||||
link_depfile: ?[]const u8,
|
link_depfile: ?[]const u8,
|
||||||
@@ -1681,7 +1680,6 @@ pub const CreateOptions = struct {
|
|||||||
verbose_llvm_ir: ?[]const u8 = null,
|
verbose_llvm_ir: ?[]const u8 = null,
|
||||||
verbose_llvm_bc: ?[]const u8 = null,
|
verbose_llvm_bc: ?[]const u8 = null,
|
||||||
link_depfile: ?[]const u8 = null,
|
link_depfile: ?[]const u8 = null,
|
||||||
verbose_cimport: bool = false,
|
|
||||||
verbose_llvm_cpu_features: bool = false,
|
verbose_llvm_cpu_features: bool = false,
|
||||||
debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,
|
debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,
|
||||||
debug_compile_errors: bool = false,
|
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_ir = options.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = options.verbose_llvm_bc,
|
.verbose_llvm_bc = options.verbose_llvm_bc,
|
||||||
.link_depfile = options.link_depfile,
|
.link_depfile = options.link_depfile,
|
||||||
.verbose_cimport = options.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = options.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = options.verbose_llvm_cpu_features,
|
||||||
.verbose_link = options.verbose_link,
|
.verbose_link = options.verbose_link,
|
||||||
.disable_c_depfile = options.disable_c_depfile,
|
.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);
|
try addModuleErrorMsg(zcu, &bundle, error_msg.*, added_any_analysis_error);
|
||||||
added_any_analysis_error = true;
|
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);
|
try zcu.addDependencyLoopErrors(&bundle);
|
||||||
for (zcu.failed_codegen.values()) |error_msg| {
|
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_generic_instances = comp.verbose_intern_pool,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.environ_map = comp.environ_map,
|
.environ_map = comp.environ_map,
|
||||||
}) catch |err| switch (err) {
|
}) catch |err| switch (err) {
|
||||||
@@ -5100,8 +5075,8 @@ pub fn obtainCObjectCacheManifest(
|
|||||||
) Cache.Manifest {
|
) Cache.Manifest {
|
||||||
var man = comp.cache_parent.obtain();
|
var man = comp.cache_parent.obtain();
|
||||||
|
|
||||||
// Only things that need to be added on top of the base hash, and only things
|
// Only things that need to be added on top of the base hash, and only
|
||||||
// that apply both to @cImport and compiling C objects. No linking stuff here!
|
// things that apply to compiling C objects. No linking stuff here!
|
||||||
// Also nothing that applies only to compiling .zig code.
|
// Also nothing that applies only to compiling .zig code.
|
||||||
cache_helpers.addModule(&man.hash, owner_mod);
|
cache_helpers.addModule(&man.hash, owner_mod);
|
||||||
man.hash.addListOfBytes(comp.global_cc_argv);
|
man.hash.addListOfBytes(comp.global_cc_argv);
|
||||||
@@ -5126,13 +5101,13 @@ pub fn obtainWin32ResourceCacheManifest(comp: *const Compilation) Cache.Manifest
|
|||||||
return man;
|
return man;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CImportResult = struct {
|
pub const TranslateCResult = struct {
|
||||||
// Only valid if `errors` is not empty
|
// Only valid if `errors` is not empty
|
||||||
digest: [Cache.bin_digest_len]u8,
|
digest: [Cache.bin_digest_len]u8,
|
||||||
cache_hit: bool,
|
cache_hit: bool,
|
||||||
errors: std.zig.ErrorBundle,
|
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);
|
result.errors.deinit(gpa);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -5142,15 +5117,12 @@ pub fn translateC(
|
|||||||
arena: Allocator,
|
arena: Allocator,
|
||||||
man: *Cache.Manifest,
|
man: *Cache.Manifest,
|
||||||
ext: FileExt,
|
ext: FileExt,
|
||||||
source: union(enum) {
|
source_path: []const u8,
|
||||||
path: []const u8,
|
|
||||||
c_src: []const u8,
|
|
||||||
},
|
|
||||||
translated_basename: []const u8,
|
translated_basename: []const u8,
|
||||||
owner_mod: *Package.Module,
|
owner_mod: *Package.Module,
|
||||||
prog_node: std.Progress.Node,
|
prog_node: std.Progress.Node,
|
||||||
environ_map: *const std.process.Environ.Map,
|
environ_map: *const std.process.Environ.Map,
|
||||||
) !CImportResult {
|
) !TranslateCResult {
|
||||||
dev.check(.translate_c_command);
|
dev.check(.translate_c_command);
|
||||||
|
|
||||||
const gpa = comp.gpa;
|
const gpa = comp.gpa;
|
||||||
@@ -5166,17 +5138,6 @@ pub fn translateC(
|
|||||||
defer cache_tmp_dir.close(io);
|
defer cache_tmp_dir.close(io);
|
||||||
|
|
||||||
const translated_path = try comp.dirs.local_cache.join(arena, &.{ tmp_sub_path, translated_basename });
|
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: {
|
const out_dep_path: ?[]const u8 = blk: {
|
||||||
if (comp.disable_c_depfile) break :blk null;
|
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(comp.global_cc_argv);
|
||||||
try argv.appendSlice(owner_mod.cc_argv);
|
try argv.appendSlice(owner_mod.cc_argv);
|
||||||
try argv.appendSlice(&.{ source_path, "-o", translated_path });
|
try argv.appendSlice(&.{ source_path, "-o", translated_path });
|
||||||
if (comp.verbose_cimport) try dumpArgv(io, argv.items);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var stdout: []u8 = undefined;
|
var stdout: []u8 = undefined;
|
||||||
try @import("main.zig").translateC(gpa, arena, io, argv.items, environ_map, prog_node, comp.thread_limit, &stdout);
|
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 (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);
|
const dep_basename = fs.path.basename(dep_file_path);
|
||||||
// Add the files depended on to the cache system, if a dep file was emitted
|
// 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) {
|
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 hex_digest = Cache.binToHex(bin_digest);
|
||||||
const o_sub_path = "o" ++ fs.path.sep_str ++ hex_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);
|
try renameTmpIntoCache(io, comp.dirs.local_cache, tmp_sub_path, o_sub_path);
|
||||||
|
|
||||||
return .{
|
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(
|
fn workerUpdateCObject(
|
||||||
comp: *Compilation,
|
comp: *Compilation,
|
||||||
c_object: *CObject,
|
c_object: *CObject,
|
||||||
@@ -7492,7 +7397,6 @@ fn buildOutputFromZig(
|
|||||||
.verbose_generic_instances = comp.verbose_intern_pool,
|
.verbose_generic_instances = comp.verbose_intern_pool,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.skip_linker_dependencies = true,
|
.skip_linker_dependencies = true,
|
||||||
@@ -7630,7 +7534,6 @@ pub fn build_crt_file(
|
|||||||
.verbose_generic_instances = comp.verbose_generic_instances,
|
.verbose_generic_instances = comp.verbose_generic_instances,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.skip_linker_dependencies = true,
|
.skip_linker_dependencies = true,
|
||||||
|
|||||||
-186
@@ -385,8 +385,6 @@ pub const Block = struct {
|
|||||||
/// What mode to generate float operations in, set by @setFloatMode
|
/// What mode to generate float operations in, set by @setFloatMode
|
||||||
float_mode: std.builtin.FloatMode = .strict,
|
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`.
|
/// 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
|
/// instruction is emitted. It signals that the innermost lexically
|
||||||
/// enclosing `block`/`block_inline` should be translated into a real AIR
|
/// enclosing `block`/`block_inline` should be translated into a real AIR
|
||||||
@@ -526,7 +524,6 @@ pub const Block = struct {
|
|||||||
.runtime_index = parent.runtime_index,
|
.runtime_index = parent.runtime_index,
|
||||||
.want_safety = parent.want_safety,
|
.want_safety = parent.want_safety,
|
||||||
.float_mode = parent.float_mode,
|
.float_mode = parent.float_mode,
|
||||||
.c_import_buf = parent.c_import_buf,
|
|
||||||
.error_return_trace_index = parent.error_return_trace_index,
|
.error_return_trace_index = parent.error_return_trace_index,
|
||||||
.need_debug_scope = parent.need_debug_scope,
|
.need_debug_scope = parent.need_debug_scope,
|
||||||
.src_base_inst = parent.src_base_inst,
|
.src_base_inst = parent.src_base_inst,
|
||||||
@@ -1189,7 +1186,6 @@ fn analyzeBodyInner(
|
|||||||
.bool_not => try sema.zirBoolNot(block, inst),
|
.bool_not => try sema.zirBoolNot(block, inst),
|
||||||
.bool_br_and => try sema.zirBoolBr(block, inst, false),
|
.bool_br_and => try sema.zirBoolBr(block, inst, false),
|
||||||
.bool_br_or => try sema.zirBoolBr(block, inst, true),
|
.bool_br_or => try sema.zirBoolBr(block, inst, true),
|
||||||
.c_import => try sema.zirCImport(block, inst),
|
|
||||||
.call => try sema.zirCall(block, inst, .direct),
|
.call => try sema.zirCall(block, inst, .direct),
|
||||||
.field_call => try sema.zirCall(block, inst, .field),
|
.field_call => try sema.zirCall(block, inst, .field),
|
||||||
.cmp_lt => try sema.zirCmp(block, inst, .lt),
|
.cmp_lt => try sema.zirCmp(block, inst, .lt),
|
||||||
@@ -1414,9 +1410,6 @@ fn analyzeBodyInner(
|
|||||||
.sub_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
.sub_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
||||||
.mul_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),
|
.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_size => try sema.zirWasmMemorySize( block, extended),
|
||||||
.wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended),
|
.wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended),
|
||||||
.prefetch => try sema.zirPrefetch( 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);
|
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 {
|
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 inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
|
||||||
const src = parent_block.nodeOffset(inst_data.src_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,
|
.is_typeof = parent_block.is_typeof,
|
||||||
.want_safety = parent_block.want_safety,
|
.want_safety = parent_block.want_safety,
|
||||||
.float_mode = parent_block.float_mode,
|
.float_mode = parent_block.float_mode,
|
||||||
.c_import_buf = parent_block.c_import_buf,
|
|
||||||
.runtime_cond = parent_block.runtime_cond,
|
.runtime_cond = parent_block.runtime_cond,
|
||||||
.runtime_loop = parent_block.runtime_loop,
|
.runtime_loop = parent_block.runtime_loop,
|
||||||
.runtime_index = parent_block.runtime_index,
|
.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(
|
fn zirWasmMemorySize(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
block: *Block,
|
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.
|
/// Do not compare directly to .True, use toBool() instead.
|
||||||
pub const Bool = enum(c_int) {
|
pub const Bool = enum(c_int) {
|
||||||
False,
|
False,
|
||||||
|
|||||||
@@ -1112,7 +1112,6 @@ fn buildSharedLib(
|
|||||||
.verbose_air = comp.verbose_air,
|
.verbose_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.version = version,
|
.version = version,
|
||||||
|
|||||||
@@ -1257,7 +1257,6 @@ fn buildSharedLib(
|
|||||||
.verbose_air = comp.verbose_air,
|
.verbose_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.version = version,
|
.version = version,
|
||||||
|
|||||||
@@ -271,7 +271,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
|
|||||||
.verbose_air = comp.verbose_air,
|
.verbose_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.skip_linker_dependencies = true,
|
.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_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.skip_linker_dependencies = true,
|
.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_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.skip_linker_dependencies = skip_linker_dependencies,
|
.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_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.skip_linker_dependencies = true,
|
.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_link = comp.verbose_link,
|
||||||
.verbose_air = comp.verbose_air,
|
.verbose_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.c_source_files = &.{
|
.c_source_files = &.{
|
||||||
|
|||||||
@@ -755,7 +755,6 @@ fn buildSharedLib(
|
|||||||
.verbose_air = comp.verbose_air,
|
.verbose_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.version = version,
|
.version = version,
|
||||||
|
|||||||
@@ -683,7 +683,6 @@ fn buildSharedLib(
|
|||||||
.verbose_air = comp.verbose_air,
|
.verbose_air = comp.verbose_air,
|
||||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||||
.verbose_cimport = comp.verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||||
.soname = soname,
|
.soname = soname,
|
||||||
|
|||||||
+5
-13
@@ -860,7 +860,6 @@ fn buildOutputType(
|
|||||||
var verbose_llvm_ir: ?[]const u8 = null;
|
var verbose_llvm_ir: ?[]const u8 = null;
|
||||||
var verbose_llvm_bc: ?[]const u8 = null;
|
var verbose_llvm_bc: ?[]const u8 = null;
|
||||||
var link_depfile: ?[]const u8 = null;
|
var link_depfile: ?[]const u8 = null;
|
||||||
var verbose_cimport = false;
|
|
||||||
var verbose_llvm_cpu_features = false;
|
var verbose_llvm_cpu_features = false;
|
||||||
var time_report = false;
|
var time_report = false;
|
||||||
var stack_report = false;
|
var stack_report = false;
|
||||||
@@ -1742,8 +1741,6 @@ fn buildOutputType(
|
|||||||
verbose_llvm_ir = rest;
|
verbose_llvm_ir = rest;
|
||||||
} else if (mem.cutPrefix(u8, arg, "--verbose-llvm-bc=")) |rest| {
|
} else if (mem.cutPrefix(u8, arg, "--verbose-llvm-bc=")) |rest| {
|
||||||
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")) {
|
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
||||||
verbose_llvm_cpu_features = true;
|
verbose_llvm_cpu_features = true;
|
||||||
} else if (mem.cutPrefix(u8, arg, "-T")) |rest| {
|
} else if (mem.cutPrefix(u8, arg, "-T")) |rest| {
|
||||||
@@ -3650,7 +3647,6 @@ fn buildOutputType(
|
|||||||
.verbose_llvm_ir = verbose_llvm_ir,
|
.verbose_llvm_ir = verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = verbose_llvm_bc,
|
.verbose_llvm_bc = verbose_llvm_bc,
|
||||||
.link_depfile = link_depfile,
|
.link_depfile = link_depfile,
|
||||||
.verbose_cimport = verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = verbose_llvm_cpu_features,
|
||||||
.time_report = time_report,
|
.time_report = time_report,
|
||||||
.stack_report = stack_report,
|
.stack_report = stack_report,
|
||||||
@@ -4289,7 +4285,7 @@ fn serve(
|
|||||||
var arena_instance = std.heap.ArenaAllocator.init(gpa);
|
var arena_instance = std.heap.ArenaAllocator.init(gpa);
|
||||||
defer arena_instance.deinit();
|
defer arena_instance.deinit();
|
||||||
const arena = arena_instance.allocator();
|
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);
|
try cmdTranslateC(comp, arena, &output, file_system_inputs, main_progress_node, environ_map);
|
||||||
defer output.deinit(gpa);
|
defer output.deinit(gpa);
|
||||||
|
|
||||||
@@ -4713,7 +4709,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)
|
|||||||
fn cmdTranslateC(
|
fn cmdTranslateC(
|
||||||
comp: *Compilation,
|
comp: *Compilation,
|
||||||
arena: Allocator,
|
arena: Allocator,
|
||||||
fancy_output: ?*Compilation.CImportResult,
|
fancy_output: ?*Compilation.TranslateCResult,
|
||||||
file_system_inputs: ?*std.ArrayList(u8),
|
file_system_inputs: ?*std.ArrayList(u8),
|
||||||
prog_node: std.Progress.Node,
|
prog_node: std.Progress.Node,
|
||||||
environ_map: *process.Environ.Map,
|
environ_map: *process.Environ.Map,
|
||||||
@@ -4735,7 +4731,7 @@ fn cmdTranslateC(
|
|||||||
Compilation.cache_helpers.hashCSource(&man, c_source_file) catch |err|
|
Compilation.cache_helpers.hashCSource(&man, c_source_file) catch |err|
|
||||||
fatal("unable to process '{s}': {t}", .{ c_source_file.src_path, 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(),
|
.digest = man.finalBin(),
|
||||||
.cache_hit = true,
|
.cache_hit = true,
|
||||||
.errors = std.zig.ErrorBundle.empty,
|
.errors = std.zig.ErrorBundle.empty,
|
||||||
@@ -4744,7 +4740,7 @@ fn cmdTranslateC(
|
|||||||
arena,
|
arena,
|
||||||
&man,
|
&man,
|
||||||
Compilation.classifyFileExt(c_source_file.src_path),
|
Compilation.classifyFileExt(c_source_file.src_path),
|
||||||
.{ .path = c_source_file.src_path },
|
c_source_file.src_path,
|
||||||
translated_basename,
|
translated_basename,
|
||||||
comp.root_mod,
|
comp.root_mod,
|
||||||
prog_node,
|
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_generic_instances = false;
|
||||||
var verbose_llvm_ir: ?[]const u8 = null;
|
var verbose_llvm_ir: ?[]const u8 = null;
|
||||||
var verbose_llvm_bc: ?[]const u8 = null;
|
var verbose_llvm_bc: ?[]const u8 = null;
|
||||||
var verbose_cimport = false;
|
|
||||||
var verbose_llvm_cpu_features = false;
|
var verbose_llvm_cpu_features = false;
|
||||||
var fetch_only = false;
|
var fetch_only = false;
|
||||||
var fetch_mode: Package.Fetch.JobQueue.Mode = .needed;
|
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;
|
verbose_llvm_ir = rest;
|
||||||
} else if (mem.cutPrefix(u8, arg, "--verbose-llvm-bc=")) |rest| {
|
} else if (mem.cutPrefix(u8, arg, "--verbose-llvm-bc=")) |rest| {
|
||||||
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")) {
|
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
||||||
verbose_llvm_cpu_features = true;
|
verbose_llvm_cpu_features = true;
|
||||||
} else if (mem.eql(u8, arg, "--color")) {
|
} 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_generic_instances = verbose_generic_instances,
|
||||||
.verbose_llvm_ir = verbose_llvm_ir,
|
.verbose_llvm_ir = verbose_llvm_ir,
|
||||||
.verbose_llvm_bc = verbose_llvm_bc,
|
.verbose_llvm_bc = verbose_llvm_bc,
|
||||||
.verbose_cimport = verbose_cimport,
|
|
||||||
.verbose_llvm_cpu_features = verbose_llvm_cpu_features,
|
.verbose_llvm_cpu_features = verbose_llvm_cpu_features,
|
||||||
.cache_mode = .whole,
|
.cache_mode = .whole,
|
||||||
.reference_trace = reference_trace,
|
.reference_trace = reference_trace,
|
||||||
@@ -5550,7 +5542,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8,
|
|||||||
.environ_map = environ_map,
|
.environ_map = environ_map,
|
||||||
}) catch |err| switch (err) {
|
}) catch |err| switch (err) {
|
||||||
error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
|
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();
|
defer comp.destroy();
|
||||||
|
|
||||||
|
|||||||
@@ -429,7 +429,6 @@ const Writer = struct {
|
|||||||
.block_inline,
|
.block_inline,
|
||||||
.suspend_block,
|
.suspend_block,
|
||||||
.loop,
|
.loop,
|
||||||
.c_import,
|
|
||||||
.typeof_builtin,
|
.typeof_builtin,
|
||||||
=> try self.writeBlock(stream, inst),
|
=> try self.writeBlock(stream, inst),
|
||||||
|
|
||||||
@@ -555,8 +554,6 @@ const Writer = struct {
|
|||||||
|
|
||||||
.tuple_decl => try self.writeTupleDecl(stream, extended),
|
.tuple_decl => try self.writeTupleDecl(stream, extended),
|
||||||
|
|
||||||
.c_undef,
|
|
||||||
.c_include,
|
|
||||||
.set_float_mode,
|
.set_float_mode,
|
||||||
.wasm_memory_size,
|
.wasm_memory_size,
|
||||||
.int_from_error,
|
.int_from_error,
|
||||||
@@ -579,7 +576,6 @@ const Writer = struct {
|
|||||||
},
|
},
|
||||||
|
|
||||||
.builtin_extern,
|
.builtin_extern,
|
||||||
.c_define,
|
|
||||||
.error_cast,
|
.error_cast,
|
||||||
.wasm_memory_grow,
|
.wasm_memory_grow,
|
||||||
.prefetch,
|
.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 = .{
|
.compile_asm = .{
|
||||||
.path = "compile_asm",
|
.path = "compile_asm",
|
||||||
},
|
},
|
||||||
.issue_794 = .{
|
|
||||||
.path = "issue_794",
|
|
||||||
},
|
|
||||||
.issue_5825 = .{
|
.issue_5825 = .{
|
||||||
.path = "issue_5825",
|
.path = "issue_5825",
|
||||||
},
|
},
|
||||||
@@ -84,9 +81,6 @@
|
|||||||
.dep_shared_builtin = .{
|
.dep_shared_builtin = .{
|
||||||
.path = "dep_shared_builtin",
|
.path = "dep_shared_builtin",
|
||||||
},
|
},
|
||||||
.dep_lazypath = .{
|
|
||||||
.path = "dep_lazypath",
|
|
||||||
},
|
|
||||||
.dirname = .{
|
.dirname = .{
|
||||||
.path = "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(.{
|
const exe = b.addExecutable(.{
|
||||||
.name = t,
|
.name = t,
|
||||||
.root_module = b.createModule(.{
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("glibc_runtime_check.zig"),
|
.root_source_file = b.path("glibc_runtime_check.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.link_libc = true,
|
.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
|
// 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 builtin = @import("builtin");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
const c_malloc = @cImport(
|
const c_malloc = @import("malloc.h"); // for reallocarray
|
||||||
@cInclude("malloc.h"), // for reallocarray
|
const c_stdlib = @import("stdlib.h"); // for atexit
|
||||||
);
|
const c_string = @import("string.h"); // for strlcpy
|
||||||
|
|
||||||
const c_stdlib = @cImport(
|
|
||||||
@cInclude("stdlib.h"), // for atexit
|
|
||||||
);
|
|
||||||
|
|
||||||
const c_string = @cImport(
|
|
||||||
@cInclude("string.h"), // for strlcpy
|
|
||||||
);
|
|
||||||
|
|
||||||
// Version of glibc this test is being built to run against
|
// Version of glibc this test is being built to run against
|
||||||
const glibc_ver = builtin.os.versionRange().gnuLibCVersion().?;
|
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,
|
.os_tag = .freestanding,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.{ .src_path = "issue_12471/main.zig" },
|
|
||||||
.{ .src_path = "guess_number/main.zig" },
|
.{ .src_path = "guess_number/main.zig" },
|
||||||
.{ .src_path = "main_return_error/error_u8.zig" },
|
.{ .src_path = "main_return_error/error_u8.zig" },
|
||||||
.{ .src_path = "main_return_error/error_u8_non_zero.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", .{});
|
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| {
|
for (code.additional_options) |option| {
|
||||||
try build_args.append(option);
|
try build_args.append(option);
|
||||||
try shell_out.print("{s} ", .{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
|
const exec_result = run(arena, io, environ_map, tmp_dir_path, build_args.items) catch
|
||||||
fatal("example failed to compile", .{});
|
fatal("example failed to compile", .{});
|
||||||
|
_ = exec_result;
|
||||||
if (code.verbose_cimport) {
|
|
||||||
const escaped_build_stderr = try escapeHtml(arena, exec_result.stderr);
|
|
||||||
try shell_out.writeAll(escaped_build_stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code.target_str) |triple| {
|
if (code.target_str) |triple| {
|
||||||
if (mem.startsWith(u8, triple, "wasm32") or
|
if (mem.startsWith(u8, triple, "wasm32") or
|
||||||
@@ -853,7 +845,6 @@ const Code = struct {
|
|||||||
link_libc: bool,
|
link_libc: bool,
|
||||||
link_mode: ?std.builtin.LinkMode,
|
link_mode: ?std.builtin.LinkMode,
|
||||||
disable_cache: bool,
|
disable_cache: bool,
|
||||||
verbose_cimport: bool,
|
|
||||||
just_check_syntax: bool,
|
just_check_syntax: bool,
|
||||||
additional_options: []const []const u8,
|
additional_options: []const []const u8,
|
||||||
use_llvm: ?bool,
|
use_llvm: ?bool,
|
||||||
@@ -915,7 +906,6 @@ fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code {
|
|||||||
var target_str: ?[]const u8 = null;
|
var target_str: ?[]const u8 = null;
|
||||||
var link_libc = false;
|
var link_libc = false;
|
||||||
var disable_cache = false;
|
var disable_cache = false;
|
||||||
var verbose_cimport = false;
|
|
||||||
var use_llvm: ?bool = null;
|
var use_llvm: ?bool = null;
|
||||||
|
|
||||||
while (it.next()) |prefixed_line| {
|
while (it.next()) |prefixed_line| {
|
||||||
@@ -940,8 +930,6 @@ fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code {
|
|||||||
link_libc = true;
|
link_libc = true;
|
||||||
} else if (mem.eql(u8, line, "disable_cache")) {
|
} else if (mem.eql(u8, line, "disable_cache")) {
|
||||||
disable_cache = true;
|
disable_cache = true;
|
||||||
} else if (mem.eql(u8, line, "verbose_cimport")) {
|
|
||||||
verbose_cimport = true;
|
|
||||||
} else {
|
} else {
|
||||||
fatal("unrecognized manifest line: {s}", .{line});
|
fatal("unrecognized manifest line: {s}", .{line});
|
||||||
}
|
}
|
||||||
@@ -956,7 +944,6 @@ fn parseManifest(arena: Allocator, source_bytes: []const u8) !Code {
|
|||||||
.link_libc = link_libc,
|
.link_libc = link_libc,
|
||||||
.link_mode = link_mode,
|
.link_mode = link_mode,
|
||||||
.disable_cache = disable_cache,
|
.disable_cache = disable_cache,
|
||||||
.verbose_cimport = verbose_cimport,
|
|
||||||
.just_check_syntax = just_check_syntax,
|
.just_check_syntax = just_check_syntax,
|
||||||
.use_llvm = use_llvm,
|
.use_llvm = use_llvm,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -249,7 +249,6 @@ const Code = struct {
|
|||||||
link_libc: bool,
|
link_libc: bool,
|
||||||
link_mode: ?std.builtin.LinkMode,
|
link_mode: ?std.builtin.LinkMode,
|
||||||
disable_cache: bool,
|
disable_cache: bool,
|
||||||
verbose_cimport: bool,
|
|
||||||
additional_options: []const []const u8,
|
additional_options: []const []const u8,
|
||||||
|
|
||||||
const Id = union(enum) {
|
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_libc = false;
|
||||||
var link_mode: ?std.builtin.LinkMode = null;
|
var link_mode: ?std.builtin.LinkMode = null;
|
||||||
var disable_cache = false;
|
var disable_cache = false;
|
||||||
var verbose_cimport = false;
|
|
||||||
var additional_options = std.array_list.Managed([]const u8).init(arena);
|
var additional_options = std.array_list.Managed([]const u8).init(arena);
|
||||||
|
|
||||||
const source_token = while (true) {
|
const source_token = while (true) {
|
||||||
@@ -340,8 +338,6 @@ fn walk(arena: Allocator, io: Io, tokenizer: *Tokenizer, out_dir: Dir, w: anytyp
|
|||||||
mode = .ReleaseSafe;
|
mode = .ReleaseSafe;
|
||||||
} else if (mem.eql(u8, end_tag_name, "code_disable_cache")) {
|
} else if (mem.eql(u8, end_tag_name, "code_disable_cache")) {
|
||||||
disable_cache = true;
|
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")) {
|
} else if (mem.eql(u8, end_tag_name, "code_link_object")) {
|
||||||
_ = try eatToken(tokenizer, .separator);
|
_ = try eatToken(tokenizer, .separator);
|
||||||
const obj_tok = try eatToken(tokenizer, .tag_content);
|
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 (link_libc) try code.print("// link_libc\n", .{});
|
||||||
if (disable_cache) try code.print("// disable_cache\n", .{});
|
if (disable_cache) try code.print("// disable_cache\n", .{});
|
||||||
if (verbose_cimport) try code.print("// verbose_cimport\n", .{});
|
|
||||||
|
|
||||||
if (link_mode) |m|
|
if (link_mode) |m|
|
||||||
try code.print("// link_mode={s}\n", .{@tagName(m)});
|
try code.print("// link_mode={s}\n", .{@tagName(m)});
|
||||||
|
|||||||
Reference in New Issue
Block a user