| author | |
| committer | |
| log | 1c24ef0d0b09a12a1fe98056f2fc04de78a82df3 |
| tree | b80e1fe8fe801541f962c1965cb84c3167a68feb |
| parent | 5087ec6f41ba928e14596e00822dc117aeb90a12 |
This allows Zig code to perform conditional compilation based on a tag
by which a Zig compiler implementation identifies itself.
See the doc comment in this commit for more details.3 files changed, 77 insertions(+), 5 deletions(-)
lib/std/builtin.zig+55| ... | ... | @@ -694,6 +694,61 @@ pub const ExternOptions = struct { |
| 694 | 694 | is_thread_local: bool = false, |
| 695 | 695 | }; |
| 696 | 696 | |
| 697 | /// This enum is set by the compiler and communicates which compiler backend is | |
| 698 | /// used to produce machine code. | |
| 699 | /// Think carefully before deciding to observe this value. Nearly all code should | |
| 700 | /// be agnostic to the backend that implements the language. The use case | |
| 701 | /// to use this value is to **work around problems with compiler implementations.** | |
| 702 | /// | |
| 703 | /// Avoid failing the compilation if the compiler backend does not match a | |
| 704 | /// whitelist of backends; rather one should detect that a known problem would | |
| 705 | /// occur in a blacklist of backends. | |
| 706 | /// | |
| 707 | /// The enum is nonexhaustive so that alternate Zig language implementations may | |
| 708 | /// choose a number as their tag (please use a random number generator rather | |
| 709 | /// than a "cute" number) and codebases can interact with these values even if | |
| 710 | /// this upstream enum does not have a name for the number. Of course, upstream | |
| 711 | /// is happy to accept pull requests to add Zig implementations to this enum. | |
| 712 | /// | |
| 713 | /// This data structure is part of the Zig language specification. | |
| 714 | pub const CompilerBackend = enum(u64) { | |
| 715 | /// It is allowed for a compiler implementation to not reveal its identity, | |
| 716 | /// in which case this value is appropriate. Be cool and make sure your | |
| 717 | /// code supports `other` Zig compilers! | |
| 718 | other = 0, | |
| 719 | /// The original Zig compiler created in 2015 by Andrew Kelley. | |
| 720 | /// Implemented in C++. Uses LLVM. | |
| 721 | stage1 = 1, | |
| 722 | /// The reference implementation self-hosted compiler of Zig, using the | |
| 723 | /// LLVM backend. | |
| 724 | stage2_llvm = 2, | |
| 725 | /// The reference implementation self-hosted compiler of Zig, using the | |
| 726 | /// backend that generates C source code. | |
| 727 | /// Note that one can observe whether the compilation will output C code | |
| 728 | /// directly with `object_format` value rather than the `compiler_backend` value. | |
| 729 | stage2_c = 3, | |
| 730 | /// The reference implementation self-hosted compiler of Zig, using the | |
| 731 | /// WebAssembly backend. | |
| 732 | stage2_wasm = 4, | |
| 733 | /// The reference implementation self-hosted compiler of Zig, using the | |
| 734 | /// arm backend. | |
| 735 | stage2_arm = 5, | |
| 736 | /// The reference implementation self-hosted compiler of Zig, using the | |
| 737 | /// x86_64 backend. | |
| 738 | stage2_x86_64 = 6, | |
| 739 | /// The reference implementation self-hosted compiler of Zig, using the | |
| 740 | /// aarch64 backend. | |
| 741 | stage2_aarch64 = 7, | |
| 742 | /// The reference implementation self-hosted compiler of Zig, using the | |
| 743 | /// x86 backend. | |
| 744 | stage2_x86 = 8, | |
| 745 | /// The reference implementation self-hosted compiler of Zig, using the | |
| 746 | /// riscv64 backend. | |
| 747 | stage2_riscv64 = 9, | |
| 748 | ||
| 749 | _, | |
| 750 | }; | |
| 751 | ||
| 697 | 752 | /// This function type is used by the Zig language code generation and |
| 698 | 753 | /// therefore must be kept in sync with the compiler implementation. |
| 699 | 754 | pub const TestFn = struct { |
src/Compilation.zig+17| ... | ... | @@ -4538,12 +4538,28 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca |
| 4538 | 4538 | const stage2_x86_cx16 = target.cpu.arch == .x86_64 and |
| 4539 | 4539 | std.Target.x86.featureSetHas(target.cpu.features, .cx16); |
| 4540 | 4540 | |
| 4541 | const zig_backend: std.builtin.CompilerBackend = blk: { | |
| 4542 | if (use_stage1) break :blk .stage1; | |
| 4543 | if (build_options.have_llvm and comp.bin_file.options.use_llvm) break :blk .stage2_llvm; | |
| 4544 | if (comp.bin_file.options.object_format == .c) break :blk .stage2_c; | |
| 4545 | break :blk switch (target.cpu.arch) { | |
| 4546 | .wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm, | |
| 4547 | .arm, .armeb, .thumb, .thumbeb => .stage2_arm, | |
| 4548 | .x86_64 => .stage2_x86_64, | |
| 4549 | .i386 => .stage2_x86, | |
| 4550 | .aarch64, .aarch64_be, .aarch64_32 => .stage2_aarch64, | |
| 4551 | .riscv64 => .stage2_riscv64, | |
| 4552 | else => .other, | |
| 4553 | }; | |
| 4554 | }; | |
| 4555 | ||
| 4541 | 4556 | @setEvalBranchQuota(4000); |
| 4542 | 4557 | try buffer.writer().print( |
| 4543 | 4558 | \\const std = @import("std"); |
| 4544 | 4559 | \\/// Zig version. When writing code that supports multiple versions of Zig, prefer |
| 4545 | 4560 | \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks. |
| 4546 | 4561 | \\pub const zig_version = std.SemanticVersion.parse("{s}") catch unreachable; |
| 4562 | \\pub const zig_backend = std.builtin.CompilerBackend.{}; | |
| 4547 | 4563 | \\/// Temporary until self-hosted is feature complete. |
| 4548 | 4564 | \\pub const zig_is_stage2 = {}; |
| 4549 | 4565 | \\/// Temporary until self-hosted supports the `cpu.arch` value. |
| ... | ... | @@ -4563,6 +4579,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca |
| 4563 | 4579 | \\ |
| 4564 | 4580 | , .{ |
| 4565 | 4581 | build_options.version, |
| 4582 | std.zig.fmtId(@tagName(zig_backend)), | |
| 4566 | 4583 | !use_stage1, |
| 4567 | 4584 | std.zig.fmtId(@tagName(target.cpu.arch)), |
| 4568 | 4585 | stage2_x86_cx16, |
test/behavior.zig+5-5| ... | ... | @@ -7,7 +7,7 @@ test { |
| 7 | 7 | _ = @import("behavior/bugs/3586.zig"); |
| 8 | 8 | _ = @import("behavior/slice_sentinel_comptime.zig"); |
| 9 | 9 | |
| 10 | if (!builtin.zig_is_stage2 or builtin.stage2_arch != .x86_64) { | |
| 10 | if (builtin.zig_backend != .stage2_x86_64) { | |
| 11 | 11 | // Tests that pass for stage1, llvm backend, C backend, wasm backend, and arm backend. |
| 12 | 12 | _ = @import("behavior/bugs/679.zig"); |
| 13 | 13 | _ = @import("behavior/bugs/4560.zig"); |
| ... | ... | @@ -19,7 +19,7 @@ test { |
| 19 | 19 | _ = @import("behavior/type_info.zig"); |
| 20 | 20 | _ = @import("behavior/type.zig"); |
| 21 | 21 | |
| 22 | if (!builtin.zig_is_stage2 or builtin.stage2_arch != .arm) { | |
| 22 | if (builtin.zig_backend != .stage2_arm) { | |
| 23 | 23 | // Tests that pass for stage1, llvm backend, C backend, wasm backend. |
| 24 | 24 | _ = @import("behavior/basic.zig"); |
| 25 | 25 | _ = @import("behavior/bitcast.zig"); |
| ... | ... | @@ -57,7 +57,7 @@ test { |
| 57 | 57 | _ = @import("behavior/void.zig"); |
| 58 | 58 | _ = @import("behavior/while.zig"); |
| 59 | 59 | |
| 60 | if (!builtin.zig_is_stage2 or builtin.stage2_arch != .wasm32) { | |
| 60 | if (builtin.zig_backend != .stage2_wasm) { | |
| 61 | 61 | // Tests that pass for stage1, llvm backend, C backend |
| 62 | 62 | _ = @import("behavior/align.zig"); |
| 63 | 63 | _ = @import("behavior/array.zig"); |
| ... | ... | @@ -67,7 +67,7 @@ test { |
| 67 | 67 | _ = @import("behavior/optional.zig"); |
| 68 | 68 | _ = @import("behavior/translate_c_macros.zig"); |
| 69 | 69 | |
| 70 | if (builtin.object_format != .c) { | |
| 70 | if (builtin.zig_backend != .stage2_c) { | |
| 71 | 71 | // Tests that pass for stage1 and the llvm backend. |
| 72 | 72 | _ = @import("behavior/align_llvm.zig"); |
| 73 | 73 | _ = @import("behavior/alignof.zig"); |
| ... | ... | @@ -109,7 +109,7 @@ test { |
| 109 | 109 | _ = @import("behavior/union.zig"); |
| 110 | 110 | _ = @import("behavior/widening.zig"); |
| 111 | 111 | |
| 112 | if (builtin.zig_is_stage2) { | |
| 112 | if (builtin.zig_backend != .stage1) { | |
| 113 | 113 | // When all comptime_memory.zig tests pass, #9646 can be closed. |
| 114 | 114 | // _ = @import("behavior/comptime_memory.zig"); |
| 115 | 115 | _ = @import("behavior/slice_stage2.zig"); |