| 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,6 +694,61 @@ pub const ExternOptions = struct { |
| 694 | is_thread_local: bool = false, | 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 | /// This function type is used by the Zig language code generation and | 752 | /// This function type is used by the Zig language code generation and |
| 698 | /// therefore must be kept in sync with the compiler implementation. | 753 | /// therefore must be kept in sync with the compiler implementation. |
| 699 | pub const TestFn = struct { | 754 | pub const TestFn = struct { |
src/Compilation.zig+17| ... | @@ -4538,12 +4538,28 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca | ... | @@ -4538,12 +4538,28 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca |
| 4538 | const stage2_x86_cx16 = target.cpu.arch == .x86_64 and | 4538 | const stage2_x86_cx16 = target.cpu.arch == .x86_64 and |
| 4539 | std.Target.x86.featureSetHas(target.cpu.features, .cx16); | 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 | @setEvalBranchQuota(4000); | 4556 | @setEvalBranchQuota(4000); |
| 4542 | try buffer.writer().print( | 4557 | try buffer.writer().print( |
| 4543 | \\const std = @import("std"); | 4558 | \\const std = @import("std"); |
| 4544 | \\/// Zig version. When writing code that supports multiple versions of Zig, prefer | 4559 | \\/// Zig version. When writing code that supports multiple versions of Zig, prefer |
| 4545 | \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks. | 4560 | \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks. |
| 4546 | \\pub const zig_version = std.SemanticVersion.parse("{s}") catch unreachable; | 4561 | \\pub const zig_version = std.SemanticVersion.parse("{s}") catch unreachable; |
| 4562 | \\pub const zig_backend = std.builtin.CompilerBackend.{}; | ||
| 4547 | \\/// Temporary until self-hosted is feature complete. | 4563 | \\/// Temporary until self-hosted is feature complete. |
| 4548 | \\pub const zig_is_stage2 = {}; | 4564 | \\pub const zig_is_stage2 = {}; |
| 4549 | \\/// Temporary until self-hosted supports the `cpu.arch` value. | 4565 | \\/// Temporary until self-hosted supports the `cpu.arch` value. |
| ... | @@ -4563,6 +4579,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca | ... | @@ -4563,6 +4579,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca |
| 4563 | \\ | 4579 | \\ |
| 4564 | , .{ | 4580 | , .{ |
| 4565 | build_options.version, | 4581 | build_options.version, |
| 4582 | std.zig.fmtId(@tagName(zig_backend)), | ||
| 4566 | !use_stage1, | 4583 | !use_stage1, |
| 4567 | std.zig.fmtId(@tagName(target.cpu.arch)), | 4584 | std.zig.fmtId(@tagName(target.cpu.arch)), |
| 4568 | stage2_x86_cx16, | 4585 | stage2_x86_cx16, |
test/behavior.zig+5-5| ... | @@ -7,7 +7,7 @@ test { | ... | @@ -7,7 +7,7 @@ test { |
| 7 | _ = @import("behavior/bugs/3586.zig"); | 7 | _ = @import("behavior/bugs/3586.zig"); |
| 8 | _ = @import("behavior/slice_sentinel_comptime.zig"); | 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 | // Tests that pass for stage1, llvm backend, C backend, wasm backend, and arm backend. | 11 | // Tests that pass for stage1, llvm backend, C backend, wasm backend, and arm backend. |
| 12 | _ = @import("behavior/bugs/679.zig"); | 12 | _ = @import("behavior/bugs/679.zig"); |
| 13 | _ = @import("behavior/bugs/4560.zig"); | 13 | _ = @import("behavior/bugs/4560.zig"); |
| ... | @@ -19,7 +19,7 @@ test { | ... | @@ -19,7 +19,7 @@ test { |
| 19 | _ = @import("behavior/type_info.zig"); | 19 | _ = @import("behavior/type_info.zig"); |
| 20 | _ = @import("behavior/type.zig"); | 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 | // Tests that pass for stage1, llvm backend, C backend, wasm backend. | 23 | // Tests that pass for stage1, llvm backend, C backend, wasm backend. |
| 24 | _ = @import("behavior/basic.zig"); | 24 | _ = @import("behavior/basic.zig"); |
| 25 | _ = @import("behavior/bitcast.zig"); | 25 | _ = @import("behavior/bitcast.zig"); |
| ... | @@ -57,7 +57,7 @@ test { | ... | @@ -57,7 +57,7 @@ test { |
| 57 | _ = @import("behavior/void.zig"); | 57 | _ = @import("behavior/void.zig"); |
| 58 | _ = @import("behavior/while.zig"); | 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 | // Tests that pass for stage1, llvm backend, C backend | 61 | // Tests that pass for stage1, llvm backend, C backend |
| 62 | _ = @import("behavior/align.zig"); | 62 | _ = @import("behavior/align.zig"); |
| 63 | _ = @import("behavior/array.zig"); | 63 | _ = @import("behavior/array.zig"); |
| ... | @@ -67,7 +67,7 @@ test { | ... | @@ -67,7 +67,7 @@ test { |
| 67 | _ = @import("behavior/optional.zig"); | 67 | _ = @import("behavior/optional.zig"); |
| 68 | _ = @import("behavior/translate_c_macros.zig"); | 68 | _ = @import("behavior/translate_c_macros.zig"); |
| 69 | 69 | ||
| 70 | if (builtin.object_format != .c) { | 70 | if (builtin.zig_backend != .stage2_c) { |
| 71 | // Tests that pass for stage1 and the llvm backend. | 71 | // Tests that pass for stage1 and the llvm backend. |
| 72 | _ = @import("behavior/align_llvm.zig"); | 72 | _ = @import("behavior/align_llvm.zig"); |
| 73 | _ = @import("behavior/alignof.zig"); | 73 | _ = @import("behavior/alignof.zig"); |
| ... | @@ -109,7 +109,7 @@ test { | ... | @@ -109,7 +109,7 @@ test { |
| 109 | _ = @import("behavior/union.zig"); | 109 | _ = @import("behavior/union.zig"); |
| 110 | _ = @import("behavior/widening.zig"); | 110 | _ = @import("behavior/widening.zig"); |
| 111 | 111 | ||
| 112 | if (builtin.zig_is_stage2) { | 112 | if (builtin.zig_backend != .stage1) { |
| 113 | // When all comptime_memory.zig tests pass, #9646 can be closed. | 113 | // When all comptime_memory.zig tests pass, #9646 can be closed. |
| 114 | // _ = @import("behavior/comptime_memory.zig"); | 114 | // _ = @import("behavior/comptime_memory.zig"); |
| 115 | _ = @import("behavior/slice_stage2.zig"); | 115 | _ = @import("behavior/slice_stage2.zig"); |