@zigc/lib 0.16.0-test.1 → 0.17.0-dev.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/c/fcntl.zig +6 -1
- package/c/inttypes.zig +0 -10
- package/c/math.zig +138 -114
- package/c/pthread.zig +57 -0
- package/c/search.zig +1 -27
- package/c/stdlib/drand48.zig +0 -57
- package/c/stdlib.zig +0 -100
- package/c/string.zig +20 -7
- package/c/strings.zig +0 -38
- package/c/stropts.zig +17 -0
- package/c/unistd.zig +27 -26
- package/c/wchar.zig +10 -0
- package/c.zig +3 -2
- package/compiler/aro/aro/Attribute/names.zig +604 -589
- package/compiler/aro/aro/Attribute.zig +202 -116
- package/compiler/aro/aro/Builtins/common.zig +874 -863
- package/compiler/aro/aro/Builtins/eval.zig +15 -7
- package/compiler/aro/aro/Builtins.zig +0 -1
- package/compiler/aro/aro/CodeGen.zig +8 -7
- package/compiler/aro/aro/Compilation.zig +137 -111
- package/compiler/aro/aro/Diagnostics.zig +21 -17
- package/compiler/aro/aro/Driver/GCCDetector.zig +635 -0
- package/compiler/aro/aro/Driver.zig +138 -63
- package/compiler/aro/aro/LangOpts.zig +12 -2
- package/compiler/aro/aro/Parser/Diagnostic.zig +79 -19
- package/compiler/aro/aro/Parser.zig +352 -153
- package/compiler/aro/aro/Pragma.zig +3 -2
- package/compiler/aro/aro/Preprocessor/Diagnostic.zig +21 -0
- package/compiler/aro/aro/Preprocessor.zig +136 -62
- package/compiler/aro/aro/Target.zig +17 -12
- package/compiler/aro/aro/Tokenizer.zig +31 -14
- package/compiler/aro/aro/Toolchain.zig +4 -7
- package/compiler/aro/aro/Tree.zig +178 -148
- package/compiler/aro/aro/TypeStore.zig +82 -24
- package/compiler/aro/aro/Value.zig +13 -17
- package/compiler/aro/aro/features.zig +1 -0
- package/compiler/aro/aro/pragmas/message.zig +3 -2
- package/compiler/aro/aro/pragmas/once.zig +0 -1
- package/compiler/aro/aro/record_layout.zig +3 -3
- package/compiler/aro/aro/text_literal.zig +3 -2
- package/compiler/aro/assembly_backend/x86_64.zig +7 -8
- package/compiler/aro/backend/Assembly.zig +1 -2
- package/compiler/aro/backend/Interner.zig +2 -2
- package/compiler/aro/backend/Ir.zig +100 -92
- package/compiler/aro/include/ptrcheck.h +49 -0
- package/compiler/aro/main.zig +26 -10
- package/compiler/build_runner.zig +1 -2
- package/compiler/objdump.zig +93 -0
- package/compiler/reduce/Walk.zig +7 -7
- package/compiler/reduce.zig +5 -1
- package/compiler/resinator/compile.zig +2 -2
- package/compiler/resinator/main.zig +7 -1
- package/compiler/resinator/preprocess.zig +1 -3
- package/compiler/std-docs.zig +8 -1
- package/compiler/test_runner.zig +194 -62
- package/compiler/translate-c/MacroTranslator.zig +80 -11
- package/compiler/translate-c/PatternList.zig +1 -9
- package/compiler/translate-c/Scope.zig +43 -6
- package/compiler/translate-c/Translator.zig +369 -127
- package/compiler/translate-c/ast.zig +19 -11
- package/compiler/translate-c/main.zig +76 -17
- package/compiler_rt/cos.zig +140 -53
- package/compiler_rt/divmodei4.zig +40 -17
- package/compiler_rt/exp.zig +1 -6
- package/compiler_rt/exp2.zig +1 -6
- package/compiler_rt/exp_f128.zig +377 -0
- package/compiler_rt/fabs.zig +0 -2
- package/compiler_rt/fma.zig +0 -2
- package/compiler_rt/fmax.zig +0 -2
- package/compiler_rt/fmin.zig +0 -2
- package/compiler_rt/fmod.zig +0 -2
- package/compiler_rt/limb64.zig +1127 -0
- package/compiler_rt/log.zig +0 -2
- package/compiler_rt/log10.zig +0 -2
- package/compiler_rt/log2.zig +0 -2
- package/compiler_rt/long_double.zig +37 -0
- package/compiler_rt/mulXi3.zig +1 -1
- package/compiler_rt/mulo.zig +6 -1
- package/compiler_rt/rem_pio2l.zig +173 -0
- package/compiler_rt/round.zig +0 -2
- package/compiler_rt/sin.zig +139 -56
- package/compiler_rt/sincos.zig +277 -72
- package/compiler_rt/sqrt.zig +0 -2
- package/compiler_rt/ssp.zig +1 -1
- package/compiler_rt/tan.zig +117 -48
- package/compiler_rt/trig.zig +256 -6
- package/compiler_rt/trunc.zig +0 -2
- package/compiler_rt/udivmodei4.zig +28 -0
- package/compiler_rt.zig +2 -0
- package/fuzzer.zig +857 -307
- package/libc/musl/arch/mipsn32/syscall_arch.h +35 -32
- package/libc/musl/src/math/pow.c +343 -0
- package/package.json +1 -1
- package/std/Build/Cache.zig +6 -6
- package/std/Build/Fuzz.zig +6 -19
- package/std/Build/Module.zig +1 -1
- package/std/Build/Step/CheckObject.zig +3 -3
- package/std/Build/Step/Compile.zig +18 -1
- package/std/Build/Step/ConfigHeader.zig +49 -33
- package/std/Build/Step/InstallArtifact.zig +18 -0
- package/std/Build/Step/Run.zig +538 -89
- package/std/Build/Step/TranslateC.zig +0 -6
- package/std/Build/Step.zig +10 -19
- package/std/Build/WebServer.zig +31 -19
- package/std/Build/abi.zig +47 -11
- package/std/Build.zig +17 -17
- package/std/Io/Dir.zig +7 -2
- package/std/Io/Dispatch.zig +5 -13
- package/std/Io/File/Reader.zig +3 -1
- package/std/Io/File/Writer.zig +8 -6
- package/std/Io/File.zig +1 -0
- package/std/Io/Kqueue.zig +2 -2
- package/std/Io/Reader.zig +8 -9
- package/std/Io/Semaphore.zig +112 -17
- package/std/Io/Terminal.zig +1 -1
- package/std/Io/Threaded.zig +352 -180
- package/std/Io/Uring.zig +15 -16
- package/std/Io/Writer.zig +46 -42
- package/std/Io/net.zig +11 -11
- package/std/Io.zig +1052 -20
- package/std/SemanticVersion.zig +1 -1
- package/std/Target/Query.zig +2 -2
- package/std/Target.zig +53 -7
- package/std/Thread.zig +8 -3
- package/std/array_hash_map.zig +105 -573
- package/std/array_list.zig +22 -31
- package/std/bit_set.zig +22 -6
- package/std/builtin/assembly.zig +68 -0
- package/std/builtin.zig +4 -0
- package/std/c/haiku.zig +3 -0
- package/std/c/serenity.zig +1 -6
- package/std/c.zig +106 -24
- package/std/compress/flate/Compress.zig +3 -3
- package/std/compress/flate/Decompress.zig +2 -3
- package/std/compress/zstd/Decompress.zig +2 -4
- package/std/crypto/Certificate/Bundle.zig +15 -1
- package/std/crypto/Certificate.zig +13 -1
- package/std/crypto/ascon.zig +75 -33
- package/std/crypto/codecs/asn1/Oid.zig +12 -1
- package/std/crypto/codecs/asn1.zig +33 -18
- package/std/crypto/codecs/base64_hex_ct.zig +16 -8
- package/std/crypto/ml_kem.zig +2 -9
- package/std/crypto/tls/Client.zig +79 -4
- package/std/crypto/tls.zig +1 -1
- package/std/crypto.zig +1 -0
- package/std/debug/Dwarf.zig +29 -9
- package/std/debug/Info.zig +4 -0
- package/std/debug/MachOFile.zig +46 -8
- package/std/debug/Pdb.zig +540 -37
- package/std/debug/SelfInfo/Elf.zig +19 -18
- package/std/debug/SelfInfo/MachO.zig +18 -7
- package/std/debug/SelfInfo/Windows.zig +138 -36
- package/std/debug.zig +181 -66
- package/std/enums.zig +25 -19
- package/std/fmt.zig +8 -3
- package/std/fs/path.zig +6 -4
- package/std/heap/ArenaAllocator.zig +145 -154
- package/std/heap/BufferFirstAllocator.zig +165 -0
- package/std/heap/debug_allocator.zig +7 -7
- package/std/heap.zig +2 -126
- package/std/http/Client.zig +31 -30
- package/std/http.zig +14 -13
- package/std/json/Scanner.zig +2 -2
- package/std/json/Stringify.zig +3 -3
- package/std/json/dynamic.zig +4 -4
- package/std/math/big/int.zig +16 -17
- package/std/mem/Allocator.zig +4 -5
- package/std/mem.zig +48 -0
- package/std/os/emscripten.zig +2 -18
- package/std/os/linux/IoUring.zig +2 -0
- package/std/os/linux/aarch64.zig +41 -12
- package/std/os/linux/arc.zig +173 -0
- package/std/os/linux/arm.zig +41 -12
- package/std/os/linux/hexagon.zig +33 -11
- package/std/os/linux/loongarch32.zig +41 -13
- package/std/os/linux/loongarch64.zig +41 -12
- package/std/os/linux/m68k.zig +41 -13
- package/std/os/linux/mips.zig +67 -36
- package/std/os/linux/mips64.zig +60 -29
- package/std/os/linux/mipsn32.zig +60 -29
- package/std/os/linux/or1k.zig +41 -12
- package/std/os/linux/powerpc.zig +41 -12
- package/std/os/linux/powerpc64.zig +41 -12
- package/std/os/linux/riscv32.zig +41 -12
- package/std/os/linux/riscv64.zig +41 -12
- package/std/os/linux/s390x.zig +44 -7
- package/std/os/linux/sparc64.zig +83 -52
- package/std/os/linux/thumb.zig +52 -36
- package/std/os/linux/x32.zig +41 -12
- package/std/os/linux/x86.zig +42 -13
- package/std/os/linux/x86_64.zig +41 -12
- package/std/os/linux.zig +419 -438
- package/std/os/uefi/tables/boot_services.zig +9 -8
- package/std/os/windows.zig +2 -2
- package/std/os.zig +41 -0
- package/std/pdb.zig +143 -4
- package/std/posix.zig +6 -12
- package/std/priority_dequeue.zig +13 -12
- package/std/priority_queue.zig +5 -4
- package/std/process/Child.zig +1 -1
- package/std/process/Environ.zig +1 -1
- package/std/process.zig +1 -1
- package/std/sort.zig +3 -3
- package/std/start.zig +17 -4
- package/std/std.zig +19 -6
- package/std/testing/FailingAllocator.zig +4 -4
- package/std/testing/Smith.zig +37 -2
- package/std/zig/Ast/Render.zig +187 -459
- package/std/zig/Ast.zig +0 -4
- package/std/zig/AstGen.zig +86 -103
- package/std/zig/AstRlAnnotate.zig +0 -11
- package/std/zig/AstSmith.zig +2602 -0
- package/std/zig/BuiltinFn.zig +0 -32
- package/std/zig/Client.zig +8 -3
- package/std/zig/LibCInstallation.zig +4 -3
- package/std/zig/Parse.zig +90 -81
- package/std/zig/Server.zig +26 -0
- package/std/zig/WindowsSdk.zig +13 -13
- package/std/zig/Zir.zig +66 -62
- package/std/zig/ZonGen.zig +6 -5
- package/std/zig/c_translation/helpers.zig +14 -9
- package/std/zig/llvm/Builder.zig +119 -60
- package/std/zig/system.zig +20 -4
- package/std/zig/tokenizer.zig +2 -1
- package/std/zig.zig +7 -10
- package/std/zip.zig +5 -5
- package/zig.h +340 -1
- package/compiler/aro/aro/Driver/Filesystem.zig +0 -241
- package/libc/mingw/complex/cabs.c +0 -48
- package/libc/mingw/complex/cabsf.c +0 -48
- package/libc/mingw/complex/cacos.c +0 -50
- package/libc/mingw/complex/cacosf.c +0 -50
- package/libc/mingw/complex/carg.c +0 -48
- package/libc/mingw/complex/cargf.c +0 -48
- package/libc/mingw/complex/casin.c +0 -50
- package/libc/mingw/complex/casinf.c +0 -50
- package/libc/mingw/complex/catan.c +0 -50
- package/libc/mingw/complex/catanf.c +0 -50
- package/libc/mingw/complex/ccos.c +0 -50
- package/libc/mingw/complex/ccosf.c +0 -50
- package/libc/mingw/complex/cexp.c +0 -48
- package/libc/mingw/complex/cexpf.c +0 -48
- package/libc/mingw/complex/cimag.c +0 -48
- package/libc/mingw/complex/cimagf.c +0 -48
- package/libc/mingw/complex/clog.c +0 -48
- package/libc/mingw/complex/clog10.c +0 -49
- package/libc/mingw/complex/clog10f.c +0 -49
- package/libc/mingw/complex/clogf.c +0 -48
- package/libc/mingw/complex/conj.c +0 -48
- package/libc/mingw/complex/conjf.c +0 -48
- package/libc/mingw/complex/cpow.c +0 -48
- package/libc/mingw/complex/cpowf.c +0 -48
- package/libc/mingw/complex/cproj.c +0 -48
- package/libc/mingw/complex/cprojf.c +0 -48
- package/libc/mingw/complex/creal.c +0 -48
- package/libc/mingw/complex/crealf.c +0 -48
- package/libc/mingw/complex/csin.c +0 -50
- package/libc/mingw/complex/csinf.c +0 -50
- package/libc/mingw/complex/csqrt.c +0 -48
- package/libc/mingw/complex/csqrtf.c +0 -48
- package/libc/mingw/complex/ctan.c +0 -50
- package/libc/mingw/complex/ctanf.c +0 -50
- package/libc/mingw/math/arm/s_rint.c +0 -86
- package/libc/mingw/math/arm/s_rintf.c +0 -51
- package/libc/mingw/math/arm/sincos.S +0 -30
- package/libc/mingw/math/arm-common/sincosl.c +0 -13
- package/libc/mingw/math/arm64/rint.c +0 -12
- package/libc/mingw/math/arm64/rintf.c +0 -12
- package/libc/mingw/math/arm64/sincos.S +0 -32
- package/libc/mingw/math/bsd_private_base.h +0 -148
- package/libc/mingw/math/fdiml.c +0 -24
- package/libc/mingw/math/frexpf.c +0 -13
- package/libc/mingw/math/frexpl.c +0 -71
- package/libc/mingw/math/x86/acosf.c +0 -29
- package/libc/mingw/math/x86/atanf.c +0 -23
- package/libc/mingw/math/x86/atanl.c +0 -18
- package/libc/mingw/math/x86/cos.def.h +0 -65
- package/libc/mingw/math/x86/cosl.c +0 -46
- package/libc/mingw/math/x86/cosl_internal.S +0 -55
- package/libc/mingw/math/x86/ldexp.c +0 -23
- package/libc/mingw/math/x86/scalbn.S +0 -41
- package/libc/mingw/math/x86/scalbnf.S +0 -40
- package/libc/mingw/math/x86/sin.def.h +0 -65
- package/libc/mingw/math/x86/sinl.c +0 -46
- package/libc/mingw/math/x86/sinl_internal.S +0 -58
- package/libc/mingw/math/x86/tanl.S +0 -62
- package/libc/mingw/misc/btowc.c +0 -28
- package/libc/mingw/misc/wcstof.c +0 -66
- package/libc/mingw/misc/wcstoimax.c +0 -132
- package/libc/mingw/misc/wcstoumax.c +0 -126
- package/libc/mingw/misc/wctob.c +0 -29
- package/libc/mingw/misc/winbs_uint64.c +0 -6
- package/libc/mingw/misc/winbs_ulong.c +0 -6
- package/libc/mingw/misc/winbs_ushort.c +0 -6
- package/libc/mingw/stdio/_Exit.c +0 -10
- package/libc/mingw/stdio/_findfirst64i32.c +0 -21
- package/libc/mingw/stdio/_findnext64i32.c +0 -21
- package/libc/mingw/stdio/_fstat64i32.c +0 -37
- package/libc/mingw/stdio/_stat64i32.c +0 -37
- package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
- package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
- package/libc/mingw/stdio/_wstat64i32.c +0 -37
- package/libc/mingw/winpthreads/spinlock.c +0 -82
- package/libc/musl/src/legacy/isastream.c +0 -7
- package/libc/musl/src/legacy/valloc.c +0 -8
- package/libc/musl/src/linux/tee.c +0 -8
- package/libc/musl/src/math/__cosl.c +0 -96
- package/libc/musl/src/math/__sinl.c +0 -78
- package/libc/musl/src/math/__tanl.c +0 -143
- package/libc/musl/src/math/aarch64/lrint.c +0 -10
- package/libc/musl/src/math/aarch64/lrintf.c +0 -10
- package/libc/musl/src/math/aarch64/rintf.c +0 -7
- package/libc/musl/src/math/cosl.c +0 -39
- package/libc/musl/src/math/fdim.c +0 -10
- package/libc/musl/src/math/fdimf.c +0 -10
- package/libc/musl/src/math/fdiml.c +0 -18
- package/libc/musl/src/math/finite.c +0 -7
- package/libc/musl/src/math/finitef.c +0 -7
- package/libc/musl/src/math/frexp.c +0 -23
- package/libc/musl/src/math/frexpf.c +0 -23
- package/libc/musl/src/math/frexpl.c +0 -29
- package/libc/musl/src/math/i386/lrint.c +0 -8
- package/libc/musl/src/math/i386/lrintf.c +0 -8
- package/libc/musl/src/math/i386/rintf.c +0 -7
- package/libc/musl/src/math/lrint.c +0 -72
- package/libc/musl/src/math/lrintf.c +0 -8
- package/libc/musl/src/math/powerpc64/lrint.c +0 -16
- package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
- package/libc/musl/src/math/rintf.c +0 -30
- package/libc/musl/src/math/s390x/rintf.c +0 -15
- package/libc/musl/src/math/sincosl.c +0 -60
- package/libc/musl/src/math/sinl.c +0 -41
- package/libc/musl/src/math/tanl.c +0 -29
- package/libc/musl/src/math/x32/lrint.s +0 -5
- package/libc/musl/src/math/x32/lrintf.s +0 -5
- package/libc/musl/src/math/x86_64/lrint.c +0 -8
- package/libc/musl/src/math/x86_64/lrintf.c +0 -8
- package/libc/musl/src/string/strdup.c +0 -10
- package/libc/musl/src/string/strndup.c +0 -12
- package/libc/musl/src/string/wcsdup.c +0 -10
- package/libc/musl/src/thread/pthread_spin_destroy.c +0 -6
- package/libc/musl/src/thread/pthread_spin_init.c +0 -6
- package/libc/musl/src/thread/pthread_spin_lock.c +0 -8
- package/libc/musl/src/thread/pthread_spin_trylock.c +0 -7
- package/libc/musl/src/thread/pthread_spin_unlock.c +0 -7
- package/libc/musl/src/unistd/dup2.c +0 -20
- package/libc/musl/src/unistd/dup3.c +0 -26
- package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
- package/libc/wasi/thread-stub/pthread_spin_lock.c +0 -8
- package/libc/wasi/thread-stub/pthread_spin_trylock.c +0 -8
- package/libc/wasi/thread-stub/pthread_spin_unlock.c +0 -7
|
@@ -19,10 +19,63 @@ const MacroTranslator = @import("MacroTranslator.zig");
|
|
|
19
19
|
const PatternList = @import("PatternList.zig");
|
|
20
20
|
const Scope = @import("Scope.zig");
|
|
21
21
|
|
|
22
|
+
const AnonymousRecordFieldNames = struct {
|
|
23
|
+
pub const Key = struct {
|
|
24
|
+
parent: QualType,
|
|
25
|
+
field: QualType,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
pub const Context = struct {
|
|
29
|
+
pub fn hash(ctx: Context, key: Key) u64 {
|
|
30
|
+
const auto_hash = std.hash_map.getAutoHashFn(Key, Context);
|
|
31
|
+
return auto_hash(ctx, .{
|
|
32
|
+
.parent = key.parent.unqualified(),
|
|
33
|
+
.field = key.field.unqualified(),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
pub fn eql(ctx: Context, a: Key, b: Key) bool {
|
|
38
|
+
const auto_eql = std.hash_map.getAutoEqlFn(Key, Context);
|
|
39
|
+
return auto_eql(ctx, .{
|
|
40
|
+
.parent = a.parent.unqualified(),
|
|
41
|
+
.field = a.field.unqualified(),
|
|
42
|
+
}, .{
|
|
43
|
+
.parent = b.parent.unqualified(),
|
|
44
|
+
.field = b.field.unqualified(),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
pub const QualTypeHashContext = struct {
|
|
51
|
+
pub fn hash(ctx: QualTypeHashContext, key: QualType) u64 {
|
|
52
|
+
const auto_hash = std.hash_map.getAutoHashFn(QualType, QualTypeHashContext);
|
|
53
|
+
return auto_hash(ctx, key.unqualified());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
pub fn eql(ctx: QualTypeHashContext, a: QualType, b: QualType) bool {
|
|
57
|
+
const auto_eql = std.hash_map.getAutoEqlFn(QualType, QualTypeHashContext);
|
|
58
|
+
return auto_eql(ctx, a.unqualified(), b.unqualified());
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
22
62
|
pub const Error = std.mem.Allocator.Error;
|
|
23
63
|
pub const MacroProcessingError = Error || error{UnexpectedMacroToken};
|
|
24
64
|
pub const TypeError = Error || error{UnsupportedType};
|
|
25
|
-
pub const TransError = TypeError || error{UnsupportedTranslation};
|
|
65
|
+
pub const TransError = TypeError || error{ UnsupportedTranslation, SelfReferential };
|
|
66
|
+
|
|
67
|
+
/// Control when to treat a trailing array as a flexible array member.
|
|
68
|
+
/// Mirrors the -fstrict-flex-arrays=<n> compiler flag.
|
|
69
|
+
pub const StrictFlexArraysLevel = enum {
|
|
70
|
+
/// Any trailing array member is a flexible array.
|
|
71
|
+
@"0",
|
|
72
|
+
/// Trailing arrays of size 0, 1, or undefined are flexible.
|
|
73
|
+
@"1",
|
|
74
|
+
/// Trailing arrays of size 0 or undefined are flexible (default).
|
|
75
|
+
@"2",
|
|
76
|
+
/// Only trailing arrays of undefined size are flexible.
|
|
77
|
+
@"3",
|
|
78
|
+
};
|
|
26
79
|
|
|
27
80
|
const Translator = @This();
|
|
28
81
|
|
|
@@ -33,6 +86,17 @@ comp: *aro.Compilation,
|
|
|
33
86
|
/// The Preprocessor that produced the source for `tree`.
|
|
34
87
|
pp: *const aro.Preprocessor,
|
|
35
88
|
|
|
89
|
+
/// Should static functions be translated as `pub`.
|
|
90
|
+
pub_static: bool,
|
|
91
|
+
/// Should function bodies be translated.
|
|
92
|
+
func_bodies: bool,
|
|
93
|
+
/// Should macro names of literals be preserved.
|
|
94
|
+
keep_macro_literals: bool,
|
|
95
|
+
/// Should struct fields be default initialized.
|
|
96
|
+
default_init: bool,
|
|
97
|
+
/// Control when to treat a trailing array as a flexible array member.
|
|
98
|
+
strict_flex_arrays: StrictFlexArraysLevel,
|
|
99
|
+
|
|
36
100
|
gpa: mem.Allocator,
|
|
37
101
|
arena: mem.Allocator,
|
|
38
102
|
|
|
@@ -44,14 +108,16 @@ mangle_count: u32 = 0,
|
|
|
44
108
|
/// Table of declarations for enum, struct, union and typedef types.
|
|
45
109
|
type_decls: std.AutoArrayHashMapUnmanaged(Node.Index, []const u8) = .empty,
|
|
46
110
|
/// Table of record decls that have been demoted to opaques.
|
|
47
|
-
opaque_demotes: std.
|
|
111
|
+
opaque_demotes: std.HashMapUnmanaged(QualType, void, QualTypeHashContext, std.hash_map.default_max_load_percentage) = .empty,
|
|
48
112
|
/// Table of unnamed enums and records that are child types of typedefs.
|
|
49
|
-
unnamed_typedefs: std.
|
|
113
|
+
unnamed_typedefs: std.HashMapUnmanaged(QualType, []const u8, QualTypeHashContext, std.hash_map.default_max_load_percentage) = .empty,
|
|
50
114
|
/// Table of anonymous record to generated field names.
|
|
51
|
-
anonymous_record_field_names: std.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
115
|
+
anonymous_record_field_names: std.HashMapUnmanaged(
|
|
116
|
+
AnonymousRecordFieldNames.Key,
|
|
117
|
+
[]const u8,
|
|
118
|
+
AnonymousRecordFieldNames.Context,
|
|
119
|
+
std.hash_map.default_max_load_percentage,
|
|
120
|
+
) = .empty,
|
|
55
121
|
|
|
56
122
|
/// This one is different than the root scope's name table. This contains
|
|
57
123
|
/// a list of names that we found by visiting all the top level decls without
|
|
@@ -75,6 +141,10 @@ typedefs: std.StringArrayHashMapUnmanaged(void) = .empty,
|
|
|
75
141
|
/// The lhs lval of a compound assignment expression.
|
|
76
142
|
compound_assign_dummy: ?ZigNode = null,
|
|
77
143
|
|
|
144
|
+
/// Set of variables whose initializers are currently being translated.
|
|
145
|
+
/// Used to detect self-referential initializers.
|
|
146
|
+
wip_var_inits: std.AutoHashMapUnmanaged(Node.Index, void) = .empty,
|
|
147
|
+
|
|
78
148
|
pub fn getMangle(t: *Translator) u32 {
|
|
79
149
|
t.mangle_count += 1;
|
|
80
150
|
return t.mangle_count;
|
|
@@ -98,10 +168,9 @@ fn maybeSuppressResult(t: *Translator, used: ResultUsed, result: ZigNode) TransE
|
|
|
98
168
|
|
|
99
169
|
pub fn addTopLevelDecl(t: *Translator, name: []const u8, decl_node: ZigNode) !void {
|
|
100
170
|
const gop = try t.global_scope.sym_table.getOrPut(t.gpa, name);
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
171
|
+
if (gop.found_existing) return; // Any duplicate decls are equivalent
|
|
172
|
+
gop.value_ptr.* = decl_node;
|
|
173
|
+
try t.global_scope.nodes.append(t.gpa, decl_node);
|
|
105
174
|
}
|
|
106
175
|
|
|
107
176
|
fn fail(
|
|
@@ -172,6 +241,12 @@ pub const Options = struct {
|
|
|
172
241
|
comp: *aro.Compilation,
|
|
173
242
|
pp: *const aro.Preprocessor,
|
|
174
243
|
tree: *const aro.Tree,
|
|
244
|
+
module_libs: bool,
|
|
245
|
+
pub_static: bool,
|
|
246
|
+
func_bodies: bool,
|
|
247
|
+
keep_macro_literals: bool,
|
|
248
|
+
default_init: bool,
|
|
249
|
+
strict_flex_arrays: StrictFlexArraysLevel,
|
|
175
250
|
};
|
|
176
251
|
|
|
177
252
|
pub fn translate(options: Options) mem.Allocator.Error![]u8 {
|
|
@@ -188,6 +263,11 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {
|
|
|
188
263
|
.comp = options.comp,
|
|
189
264
|
.pp = options.pp,
|
|
190
265
|
.tree = options.tree,
|
|
266
|
+
.pub_static = options.pub_static,
|
|
267
|
+
.func_bodies = options.func_bodies,
|
|
268
|
+
.keep_macro_literals = options.keep_macro_literals,
|
|
269
|
+
.default_init = options.default_init,
|
|
270
|
+
.strict_flex_arrays = options.strict_flex_arrays,
|
|
191
271
|
};
|
|
192
272
|
translator.global_scope.* = Scope.Root.init(&translator);
|
|
193
273
|
defer {
|
|
@@ -200,6 +280,7 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {
|
|
|
200
280
|
translator.anonymous_record_field_names.deinit(gpa);
|
|
201
281
|
translator.typedefs.deinit(gpa);
|
|
202
282
|
translator.global_scope.deinit();
|
|
283
|
+
translator.wip_var_inits.deinit(gpa);
|
|
203
284
|
}
|
|
204
285
|
|
|
205
286
|
try translator.prepopulateGlobalNameTable();
|
|
@@ -227,7 +308,6 @@ pub fn translate(options: Options) mem.Allocator.Error![]u8 {
|
|
|
227
308
|
\\pub const __builtin = @import("std").zig.c_translation.builtins;
|
|
228
309
|
\\pub const __helpers = @import("std").zig.c_translation.helpers;
|
|
229
310
|
\\
|
|
230
|
-
\\
|
|
231
311
|
) catch return error.OutOfMemory;
|
|
232
312
|
|
|
233
313
|
var zig_ast = try ast.render(gpa, translator.global_scope.nodes.items);
|
|
@@ -261,10 +341,12 @@ fn prepopulateGlobalNameTable(t: *Translator) !void {
|
|
|
261
341
|
const gop = try t.unnamed_typedefs.getOrPut(t.gpa, base.qt);
|
|
262
342
|
if (gop.found_existing) {
|
|
263
343
|
// One typedef can declare multiple names.
|
|
264
|
-
//
|
|
344
|
+
// Don't put this one in `decl_table` so it's processed later.
|
|
265
345
|
continue;
|
|
266
346
|
}
|
|
267
347
|
gop.value_ptr.* = decl_name;
|
|
348
|
+
try t.type_decls.put(t.gpa, decl, decl_name);
|
|
349
|
+
try t.typedefs.put(t.gpa, decl_name, {});
|
|
268
350
|
},
|
|
269
351
|
|
|
270
352
|
.struct_decl,
|
|
@@ -344,15 +426,26 @@ fn transDecl(t: *Translator, scope: *Scope, decl: Node.Index) !void {
|
|
|
344
426
|
try t.transRecordDecl(scope, record_decl.container_qt);
|
|
345
427
|
},
|
|
346
428
|
|
|
429
|
+
.struct_forward_decl, .union_forward_decl => |record_decl| {
|
|
430
|
+
if (record_decl.definition) |some| {
|
|
431
|
+
return t.transDecl(scope, some);
|
|
432
|
+
}
|
|
433
|
+
try t.transRecordDecl(scope, record_decl.container_qt);
|
|
434
|
+
},
|
|
435
|
+
|
|
347
436
|
.enum_decl => |enum_decl| {
|
|
348
437
|
try t.transEnumDecl(scope, enum_decl.container_qt);
|
|
349
438
|
},
|
|
350
439
|
|
|
440
|
+
.enum_forward_decl => |enum_decl| {
|
|
441
|
+
if (enum_decl.definition) |some| {
|
|
442
|
+
return t.transDecl(scope, some);
|
|
443
|
+
}
|
|
444
|
+
try t.transEnumDecl(scope, enum_decl.container_qt);
|
|
445
|
+
},
|
|
446
|
+
|
|
351
447
|
.enum_field,
|
|
352
448
|
.record_field,
|
|
353
|
-
.struct_forward_decl,
|
|
354
|
-
.union_forward_decl,
|
|
355
|
-
.enum_forward_decl,
|
|
356
449
|
=> return,
|
|
357
450
|
|
|
358
451
|
.function => |function| {
|
|
@@ -364,7 +457,7 @@ fn transDecl(t: *Translator, scope: *Scope, decl: Node.Index) !void {
|
|
|
364
457
|
|
|
365
458
|
.variable => |variable| {
|
|
366
459
|
if (variable.definition != null) return;
|
|
367
|
-
try t.transVarDecl(scope, variable);
|
|
460
|
+
try t.transVarDecl(scope, variable, decl);
|
|
368
461
|
},
|
|
369
462
|
.static_assert => |static_assert| {
|
|
370
463
|
try t.transStaticAssert(&t.global_scope.base, static_assert);
|
|
@@ -382,8 +475,12 @@ pub const builtin_typedef_map = std.StaticStringMap([]const u8).initComptime(.{
|
|
|
382
475
|
.{ "int8_t", "i8" },
|
|
383
476
|
.{ "uint16_t", "u16" },
|
|
384
477
|
.{ "int16_t", "i16" },
|
|
478
|
+
.{ "uint24_t", "u24" },
|
|
479
|
+
.{ "int24_t", "i24" },
|
|
385
480
|
.{ "uint32_t", "u32" },
|
|
386
481
|
.{ "int32_t", "i32" },
|
|
482
|
+
.{ "uint48_t", "u48" },
|
|
483
|
+
.{ "int48_t", "i48" },
|
|
387
484
|
.{ "uint64_t", "u64" },
|
|
388
485
|
.{ "int64_t", "i64" },
|
|
389
486
|
.{ "intptr_t", "isize" },
|
|
@@ -531,13 +628,6 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|
|
531
628
|
break :init ZigTag.opaque_literal.init();
|
|
532
629
|
}
|
|
533
630
|
|
|
534
|
-
// Demote record to opaque if it contains an opaque field
|
|
535
|
-
if (t.typeWasDemotedToOpaque(field.qt)) {
|
|
536
|
-
try t.opaque_demotes.put(t.gpa, base.qt, {});
|
|
537
|
-
try t.warn(scope, field_loc, "{s} demoted to opaque type - has opaque field", .{container_kind_name});
|
|
538
|
-
break :init ZigTag.opaque_literal.init();
|
|
539
|
-
}
|
|
540
|
-
|
|
541
631
|
var field_name = field.name.lookup(t.comp);
|
|
542
632
|
if (field.name_tok == 0) {
|
|
543
633
|
field_name = try std.fmt.allocPrint(t.arena, "unnamed_{d}", .{unnamed_field_count});
|
|
@@ -548,23 +638,22 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|
|
548
638
|
}, field_name);
|
|
549
639
|
}
|
|
550
640
|
|
|
551
|
-
const field_alignment = if (has_alignment_attributes)
|
|
552
|
-
t.alignmentForField(record_ty, head_field_alignment, field_index)
|
|
553
|
-
else
|
|
554
|
-
null;
|
|
555
|
-
|
|
556
641
|
const field_type = field_type: {
|
|
557
642
|
// Check if this is a flexible array member.
|
|
558
643
|
flexible: {
|
|
559
644
|
if (field_index != record_ty.fields.len - 1 and container_kind != .@"union") break :flexible;
|
|
560
645
|
const array_ty = field.qt.get(t.comp, .array) orelse break :flexible;
|
|
561
|
-
if (
|
|
646
|
+
if (!t.isFlexibleArrayLen(array_ty.len)) break :flexible;
|
|
562
647
|
|
|
563
648
|
const elem_type = t.transType(scope, array_ty.elem, field_loc) catch |err| switch (err) {
|
|
564
649
|
error.UnsupportedType => break :flexible,
|
|
565
650
|
else => |e| return e,
|
|
566
651
|
};
|
|
567
|
-
const
|
|
652
|
+
const backing_array_len: usize = switch (array_ty.len) {
|
|
653
|
+
.fixed => |n| @intCast(n),
|
|
654
|
+
else => 0,
|
|
655
|
+
};
|
|
656
|
+
const backing_array = try ZigTag.array_type.create(t.arena, .{ .len = backing_array_len, .elem_type = elem_type });
|
|
568
657
|
|
|
569
658
|
const member_name = field_name;
|
|
570
659
|
field_name = try std.fmt.allocPrint(t.arena, "_{s}", .{field_name});
|
|
@@ -572,7 +661,7 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|
|
572
661
|
const member = try t.createFlexibleMemberFn(member_name, field_name);
|
|
573
662
|
try functions.append(t.gpa, member);
|
|
574
663
|
|
|
575
|
-
break :field_type
|
|
664
|
+
break :field_type backing_array;
|
|
576
665
|
}
|
|
577
666
|
|
|
578
667
|
break :field_type t.transType(scope, field.qt, field_loc) catch |err| switch (err) {
|
|
@@ -588,10 +677,22 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|
|
588
677
|
};
|
|
589
678
|
};
|
|
590
679
|
|
|
680
|
+
// Demote record to opaque if it contains an opaque field
|
|
681
|
+
if (t.typeWasDemotedToOpaque(field.qt)) {
|
|
682
|
+
try t.opaque_demotes.put(t.gpa, base.qt, {});
|
|
683
|
+
try t.warn(scope, field_loc, "{s} demoted to opaque type - has opaque field", .{container_kind_name});
|
|
684
|
+
break :init ZigTag.opaque_literal.init();
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const field_alignment = if (has_alignment_attributes)
|
|
688
|
+
t.alignmentForField(record_ty, head_field_alignment, field_index)
|
|
689
|
+
else
|
|
690
|
+
null;
|
|
691
|
+
|
|
591
692
|
// C99 introduced designated initializers for structs. Omitted fields are implicitly
|
|
592
693
|
// initialized to zero. Some C APIs are designed with this in mind. Defaulting to zero
|
|
593
694
|
// values for translated struct fields permits Zig code to comfortably use such an API.
|
|
594
|
-
const default_value = if (container_kind == .@"struct")
|
|
695
|
+
const default_value = if (t.default_init and container_kind == .@"struct")
|
|
595
696
|
try t.createZeroValueNode(field.qt, field_type, .no_as)
|
|
596
697
|
else
|
|
597
698
|
null;
|
|
@@ -616,7 +717,7 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|
|
616
717
|
.name = "_padding",
|
|
617
718
|
.type = try ZigTag.type.create(t.arena, try std.fmt.allocPrint(t.arena, "u{d}", .{padding_bits})),
|
|
618
719
|
.alignment = @divExact(alignment_bits, 8),
|
|
619
|
-
.default_value = if (container_kind == .@"struct")
|
|
720
|
+
.default_value = if (t.default_init and container_kind == .@"struct")
|
|
620
721
|
ZigTag.zero_literal.init()
|
|
621
722
|
else
|
|
622
723
|
null,
|
|
@@ -663,14 +764,12 @@ fn transRecordDecl(t: *Translator, scope: *Scope, record_qt: QualType) Error!voi
|
|
|
663
764
|
fn transFnDecl(t: *Translator, scope: *Scope, function: Node.Function) Error!void {
|
|
664
765
|
const func_ty = function.qt.get(t.comp, .func).?;
|
|
665
766
|
|
|
666
|
-
const is_pub = scope.id == .root;
|
|
667
|
-
|
|
668
767
|
const fn_name = t.tree.tokSlice(function.name_tok);
|
|
669
768
|
if (scope.getAlias(fn_name) != null or t.global_scope.containsNow(fn_name))
|
|
670
769
|
return; // Avoid processing this decl twice
|
|
671
770
|
|
|
672
771
|
const fn_decl_loc = function.name_tok;
|
|
673
|
-
const has_body = function.body != null and func_ty.kind != .variadic;
|
|
772
|
+
const has_body = function.body != null and func_ty.kind != .variadic and t.func_bodies;
|
|
674
773
|
if (function.body != null and func_ty.kind == .variadic) {
|
|
675
774
|
try t.warn(scope, function.name_tok, "TODO unable to translate variadic function, demoted to extern", .{});
|
|
676
775
|
}
|
|
@@ -681,7 +780,7 @@ fn transFnDecl(t: *Translator, scope: *Scope, function: Node.Function) Error!voi
|
|
|
681
780
|
.is_always_inline = is_always_inline,
|
|
682
781
|
.is_extern = !has_body,
|
|
683
782
|
.is_export = !function.static and has_body and !is_always_inline and !function.@"inline",
|
|
684
|
-
.is_pub =
|
|
783
|
+
.is_pub = scope.id == .root and (!function.static or t.pub_static),
|
|
685
784
|
.has_body = has_body,
|
|
686
785
|
.cc = if (function.qt.getAttribute(t.comp, .calling_convention)) |some| switch (some.cc) {
|
|
687
786
|
.c => .c,
|
|
@@ -761,6 +860,7 @@ fn transFnDecl(t: *Translator, scope: *Scope, function: Node.Function) Error!voi
|
|
|
761
860
|
|
|
762
861
|
t.transCompoundStmtInline(body_stmt, &block_scope) catch |err| switch (err) {
|
|
763
862
|
error.OutOfMemory => |e| return e,
|
|
863
|
+
error.SelfReferential => unreachable,
|
|
764
864
|
error.UnsupportedTranslation,
|
|
765
865
|
error.UnsupportedType,
|
|
766
866
|
=> {
|
|
@@ -777,7 +877,7 @@ fn transFnDecl(t: *Translator, scope: *Scope, function: Node.Function) Error!voi
|
|
|
777
877
|
return t.addTopLevelDecl(fn_name, proto_node);
|
|
778
878
|
}
|
|
779
879
|
|
|
780
|
-
fn transVarDecl(t: *Translator, scope: *Scope, variable: Node.Variable) Error!void {
|
|
880
|
+
fn transVarDecl(t: *Translator, scope: *Scope, variable: Node.Variable, decl_node: Node.Index) Error!void {
|
|
781
881
|
const base_name = t.tree.tokSlice(variable.name_tok);
|
|
782
882
|
const toplevel = scope.id == .root;
|
|
783
883
|
const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(t) else undefined;
|
|
@@ -815,24 +915,28 @@ fn transVarDecl(t: *Translator, scope: *Scope, variable: Node.Variable) Error!vo
|
|
|
815
915
|
var is_const = variable.qt.@"const" or (array_ty != null and array_ty.?.elem.@"const");
|
|
816
916
|
var is_extern = variable.storage_class == .@"extern";
|
|
817
917
|
|
|
918
|
+
var self_referential = false;
|
|
818
919
|
const init_node = init: {
|
|
819
920
|
if (variable.initializer) |init| {
|
|
820
921
|
const maybe_literal = init.get(t.tree);
|
|
922
|
+
if (!toplevel) try t.wip_var_inits.putNoClobber(t.gpa, decl_node, {});
|
|
923
|
+
defer _ = t.wip_var_inits.remove(decl_node);
|
|
924
|
+
|
|
821
925
|
const init_node = (if (maybe_literal == .string_literal_expr)
|
|
822
926
|
t.transStringLiteralInitializer(init, maybe_literal.string_literal_expr, type_node)
|
|
823
927
|
else
|
|
824
928
|
t.transExprCoercing(scope, init, .used)) catch |err| switch (err) {
|
|
929
|
+
error.SelfReferential => {
|
|
930
|
+
self_referential = true;
|
|
931
|
+
break :init ZigTag.undefined_literal.init();
|
|
932
|
+
},
|
|
825
933
|
error.UnsupportedTranslation, error.UnsupportedType => {
|
|
826
934
|
return t.failDecl(scope, variable.name_tok, name, "unable to resolve var init expr", .{});
|
|
827
935
|
},
|
|
828
936
|
else => |e| return e,
|
|
829
937
|
};
|
|
830
938
|
|
|
831
|
-
|
|
832
|
-
break :init try ZigTag.int_from_bool.create(t.arena, init_node);
|
|
833
|
-
} else {
|
|
834
|
-
break :init init_node;
|
|
835
|
-
}
|
|
939
|
+
break :init try t.toNonBool(init_node, variable.qt);
|
|
836
940
|
}
|
|
837
941
|
if (variable.storage_class == .@"extern") {
|
|
838
942
|
if (array_ty != null and array_ty.?.len == .incomplete) {
|
|
@@ -876,7 +980,7 @@ fn transVarDecl(t: *Translator, scope: *Scope, variable: Node.Variable) Error!vo
|
|
|
876
980
|
const alignment: ?c_uint = variable.qt.requestedAlignment(t.comp) orelse null;
|
|
877
981
|
var node = try ZigTag.var_decl.create(t.arena, .{
|
|
878
982
|
.is_pub = toplevel,
|
|
879
|
-
.is_const = is_const,
|
|
983
|
+
.is_const = is_const and !self_referential,
|
|
880
984
|
.is_extern = is_extern,
|
|
881
985
|
.is_export = toplevel and variable.storage_class == .auto and linkage == .strong,
|
|
882
986
|
.is_threadlocal = variable.thread_local,
|
|
@@ -894,6 +998,21 @@ fn transVarDecl(t: *Translator, scope: *Scope, variable: Node.Variable) Error!vo
|
|
|
894
998
|
node = try ZigTag.wrapped_local.create(t.arena, .{ .name = name, .init = node });
|
|
895
999
|
}
|
|
896
1000
|
try scope.appendNode(node);
|
|
1001
|
+
if (self_referential) {
|
|
1002
|
+
const deferred_init = t.transExprCoercing(scope, variable.initializer.?, .used) catch |err| switch (err) {
|
|
1003
|
+
error.SelfReferential => unreachable,
|
|
1004
|
+
error.UnsupportedTranslation, error.UnsupportedType => {
|
|
1005
|
+
return t.failDecl(scope, variable.name_tok, name, "unable to resolve var init expr", .{});
|
|
1006
|
+
},
|
|
1007
|
+
else => |e| return e,
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
const assign = try ZigTag.assign.create(t.arena, .{
|
|
1011
|
+
.lhs = try ZigTag.identifier.create(t.arena, name),
|
|
1012
|
+
.rhs = try t.toNonBool(deferred_init, variable.qt),
|
|
1013
|
+
});
|
|
1014
|
+
try scope.appendNode(assign);
|
|
1015
|
+
}
|
|
897
1016
|
try bs.discardVariable(name);
|
|
898
1017
|
|
|
899
1018
|
if (variable.qt.getAttribute(t.comp, .cleanup)) |cleanup_attr| {
|
|
@@ -1001,6 +1120,7 @@ fn transEnumDecl(t: *Translator, scope: *Scope, enum_qt: QualType) Error!void {
|
|
|
1001
1120
|
|
|
1002
1121
|
fn transStaticAssert(t: *Translator, scope: *Scope, static_assert: Node.StaticAssert) Error!void {
|
|
1003
1122
|
const condition = t.transExpr(scope, static_assert.cond, .used) catch |err| switch (err) {
|
|
1123
|
+
error.SelfReferential => unreachable,
|
|
1004
1124
|
error.UnsupportedTranslation, error.UnsupportedType => {
|
|
1005
1125
|
return try t.warn(&t.global_scope.base, static_assert.cond.tok(t.tree), "unable to translate _Static_assert condition", .{});
|
|
1006
1126
|
},
|
|
@@ -1084,21 +1204,17 @@ fn transType(t: *Translator, scope: *Scope, qt: QualType, source_loc: TokenIndex
|
|
|
1084
1204
|
},
|
|
1085
1205
|
.float => |float_ty| switch (float_ty) {
|
|
1086
1206
|
.fp16, .float16 => return ZigTag.type.create(t.arena, "f16"),
|
|
1087
|
-
.float => return ZigTag.type.create(t.arena, "f32"),
|
|
1088
|
-
.double => return ZigTag.type.create(t.arena, "f64"),
|
|
1089
|
-
.long_double => return ZigTag.type.create(t.arena, "c_longdouble"),
|
|
1207
|
+
.float, .float32 => return ZigTag.type.create(t.arena, "f32"),
|
|
1208
|
+
.double, .float64, .float32x => return ZigTag.type.create(t.arena, "f64"),
|
|
1209
|
+
.long_double, .float64x => return ZigTag.type.create(t.arena, "c_longdouble"),
|
|
1090
1210
|
.float128 => return ZigTag.type.create(t.arena, "f128"),
|
|
1091
|
-
.bf16,
|
|
1092
|
-
.float32,
|
|
1093
|
-
.float64,
|
|
1094
|
-
.float32x,
|
|
1095
|
-
.float64x,
|
|
1096
|
-
.float128x,
|
|
1211
|
+
.bf16 => return t.fail(error.UnsupportedType, source_loc, "TODO support bfloat16", .{}),
|
|
1097
1212
|
.dfloat32,
|
|
1098
1213
|
.dfloat64,
|
|
1099
1214
|
.dfloat128,
|
|
1100
1215
|
.dfloat64x,
|
|
1101
|
-
=> return t.fail(error.UnsupportedType, source_loc, "TODO support float type: '{s}'", .{try t.getTypeStr(qt)}),
|
|
1216
|
+
=> return t.fail(error.UnsupportedType, source_loc, "TODO support decimal float type: '{s}'", .{try t.getTypeStr(qt)}),
|
|
1217
|
+
.float128x => unreachable, // Unsupported on all targets
|
|
1102
1218
|
},
|
|
1103
1219
|
.pointer => |pointer_ty| {
|
|
1104
1220
|
const child_qt = pointer_ty.child;
|
|
@@ -1173,9 +1289,21 @@ fn transType(t: *Translator, scope: *Scope, qt: QualType, source_loc: TokenIndex
|
|
|
1173
1289
|
return ZigTag.identifier.create(t.arena, name);
|
|
1174
1290
|
},
|
|
1175
1291
|
.attributed => |attributed_ty| continue :loop attributed_ty.base.type(t.comp),
|
|
1176
|
-
.typeof => |typeof_ty|
|
|
1292
|
+
.typeof => |typeof_ty| {
|
|
1293
|
+
if (typeof_ty.expr) |expr| {
|
|
1294
|
+
if (t.transExpr(scope, expr, .used)) |node| {
|
|
1295
|
+
return ZigTag.typeof.create(t.arena, node);
|
|
1296
|
+
} else |err| switch (err) {
|
|
1297
|
+
error.SelfReferential => {},
|
|
1298
|
+
error.UnsupportedTranslation => {},
|
|
1299
|
+
error.UnsupportedType => {},
|
|
1300
|
+
error.OutOfMemory => |e| return e,
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
continue :loop typeof_ty.base.type(t.comp);
|
|
1304
|
+
},
|
|
1177
1305
|
.vector => |vector_ty| {
|
|
1178
|
-
const len = try t.createNumberNode(vector_ty.len
|
|
1306
|
+
const len = try t.createNumberNode(vector_ty.len);
|
|
1179
1307
|
const elem_type = try t.transType(scope, vector_ty.elem, source_loc);
|
|
1180
1308
|
return ZigTag.vector.create(t.arena, .{ .lhs = len, .rhs = elem_type });
|
|
1181
1309
|
},
|
|
@@ -1384,7 +1512,10 @@ fn transFnType(
|
|
|
1384
1512
|
.is_var_args = switch (func_ty.kind) {
|
|
1385
1513
|
.normal => false,
|
|
1386
1514
|
.variadic => true,
|
|
1387
|
-
.old_style =>
|
|
1515
|
+
.old_style => if (t.comp.target.cpu.arch.isWasm())
|
|
1516
|
+
false
|
|
1517
|
+
else
|
|
1518
|
+
!ctx.is_export and !ctx.is_always_inline and !ctx.has_body,
|
|
1388
1519
|
},
|
|
1389
1520
|
.name = ctx.fn_name,
|
|
1390
1521
|
.linksection_string = linksection_string,
|
|
@@ -1468,7 +1599,7 @@ fn typeIsOpaque(t: *Translator, qt: QualType) bool {
|
|
|
1468
1599
|
}
|
|
1469
1600
|
|
|
1470
1601
|
fn typeWasDemotedToOpaque(t: *Translator, qt: QualType) bool {
|
|
1471
|
-
return t.opaque_demotes.contains(qt);
|
|
1602
|
+
return t.opaque_demotes.contains(qt.base(t.comp).qt);
|
|
1472
1603
|
}
|
|
1473
1604
|
|
|
1474
1605
|
fn typeHasWrappingOverflow(t: *Translator, qt: QualType) bool {
|
|
@@ -1531,16 +1662,30 @@ fn transStmt(t: *Translator, scope: *Scope, stmt: Node.Index) TransError!ZigNode
|
|
|
1531
1662
|
try t.transRecordDecl(scope, record_decl.container_qt);
|
|
1532
1663
|
return ZigTag.declaration.init();
|
|
1533
1664
|
},
|
|
1665
|
+
.struct_forward_decl, .union_forward_decl => |record_decl| {
|
|
1666
|
+
if (record_decl.definition) |some| {
|
|
1667
|
+
return t.transStmt(scope, some);
|
|
1668
|
+
}
|
|
1669
|
+
try t.transRecordDecl(scope, record_decl.container_qt);
|
|
1670
|
+
return ZigTag.declaration.init();
|
|
1671
|
+
},
|
|
1534
1672
|
.enum_decl => |enum_decl| {
|
|
1535
1673
|
try t.transEnumDecl(scope, enum_decl.container_qt);
|
|
1536
1674
|
return ZigTag.declaration.init();
|
|
1537
1675
|
},
|
|
1676
|
+
.enum_forward_decl => |enum_decl| {
|
|
1677
|
+
if (enum_decl.definition) |some| {
|
|
1678
|
+
return t.transStmt(scope, some);
|
|
1679
|
+
}
|
|
1680
|
+
try t.transEnumDecl(scope, enum_decl.container_qt);
|
|
1681
|
+
return ZigTag.declaration.init();
|
|
1682
|
+
},
|
|
1538
1683
|
.function => |function| {
|
|
1539
1684
|
try t.transFnDecl(scope, function);
|
|
1540
1685
|
return ZigTag.declaration.init();
|
|
1541
1686
|
},
|
|
1542
1687
|
.variable => |variable| {
|
|
1543
|
-
try t.transVarDecl(scope, variable);
|
|
1688
|
+
try t.transVarDecl(scope, variable, stmt);
|
|
1544
1689
|
return ZigTag.declaration.init();
|
|
1545
1690
|
},
|
|
1546
1691
|
.switch_stmt => |switch_stmt| return t.transSwitch(scope, switch_stmt),
|
|
@@ -1562,7 +1707,10 @@ fn transCompoundStmtInline(t: *Translator, compound: Node.CompoundStmt, block: *
|
|
|
1562
1707
|
const result = try t.transStmt(&block.base, stmt);
|
|
1563
1708
|
switch (result.tag()) {
|
|
1564
1709
|
.declaration, .empty_block => {},
|
|
1565
|
-
else =>
|
|
1710
|
+
else => {
|
|
1711
|
+
try block.statements.append(t.gpa, result);
|
|
1712
|
+
if (result.isNoreturn()) return;
|
|
1713
|
+
},
|
|
1566
1714
|
}
|
|
1567
1715
|
}
|
|
1568
1716
|
}
|
|
@@ -1578,12 +1726,9 @@ fn transReturnStmt(t: *Translator, scope: *Scope, return_stmt: Node.ReturnStmt)
|
|
|
1578
1726
|
switch (return_stmt.operand) {
|
|
1579
1727
|
.none => return ZigTag.return_void.init(),
|
|
1580
1728
|
.expr => |operand| {
|
|
1581
|
-
|
|
1729
|
+
const rhs = try t.transExprCoercing(scope, operand, .used);
|
|
1582
1730
|
const return_qt = scope.findBlockReturnType();
|
|
1583
|
-
|
|
1584
|
-
rhs = try ZigTag.int_from_bool.create(t.arena, rhs);
|
|
1585
|
-
}
|
|
1586
|
-
return ZigTag.@"return".create(t.arena, rhs);
|
|
1731
|
+
return ZigTag.@"return".create(t.arena, try t.toNonBool(rhs, return_qt));
|
|
1587
1732
|
},
|
|
1588
1733
|
.implicit => |zero| {
|
|
1589
1734
|
if (zero) return ZigTag.@"return".create(t.arena, ZigTag.zero_literal.init());
|
|
@@ -1698,7 +1843,7 @@ fn transDoWhileStmt(t: *Translator, scope: *Scope, do_stmt: Node.DoWhileStmt) Tr
|
|
|
1698
1843
|
};
|
|
1699
1844
|
|
|
1700
1845
|
var body_node = try t.transStmt(&loop_scope, do_stmt.body);
|
|
1701
|
-
if (body_node.isNoreturn(
|
|
1846
|
+
if (body_node.isNoreturn()) {
|
|
1702
1847
|
// The body node ends in a noreturn statement. Simply put it in a while (true)
|
|
1703
1848
|
// in case it contains breaks or continues.
|
|
1704
1849
|
} else if (do_stmt.body.get(t.tree) == .compound_stmt) {
|
|
@@ -1918,8 +2063,6 @@ fn transSwitchProngStmt(
|
|
|
1918
2063
|
body: []const Node.Index,
|
|
1919
2064
|
) TransError!ZigNode {
|
|
1920
2065
|
switch (stmt.get(t.tree)) {
|
|
1921
|
-
.break_stmt => return ZigTag.@"break".init(),
|
|
1922
|
-
.return_stmt => return t.transStmt(scope, stmt),
|
|
1923
2066
|
.case_stmt, .default_stmt => unreachable,
|
|
1924
2067
|
else => {
|
|
1925
2068
|
var block_scope = try Scope.Block.init(t, scope, false);
|
|
@@ -1940,15 +2083,6 @@ fn transSwitchProngStmtInline(
|
|
|
1940
2083
|
) TransError!void {
|
|
1941
2084
|
for (body) |stmt| {
|
|
1942
2085
|
switch (stmt.get(t.tree)) {
|
|
1943
|
-
.return_stmt => {
|
|
1944
|
-
const result = try t.transStmt(&block.base, stmt);
|
|
1945
|
-
try block.statements.append(t.gpa, result);
|
|
1946
|
-
return;
|
|
1947
|
-
},
|
|
1948
|
-
.break_stmt => {
|
|
1949
|
-
try block.statements.append(t.gpa, ZigTag.@"break".init());
|
|
1950
|
-
return;
|
|
1951
|
-
},
|
|
1952
2086
|
.case_stmt => |case_stmt| {
|
|
1953
2087
|
var sub = case_stmt.body;
|
|
1954
2088
|
while (true) switch (sub.get(t.tree)) {
|
|
@@ -1959,7 +2093,7 @@ fn transSwitchProngStmtInline(
|
|
|
1959
2093
|
const result = try t.transStmt(&block.base, sub);
|
|
1960
2094
|
assert(result.tag() != .declaration);
|
|
1961
2095
|
try block.statements.append(t.gpa, result);
|
|
1962
|
-
if (result.isNoreturn(
|
|
2096
|
+
if (result.isNoreturn()) return;
|
|
1963
2097
|
},
|
|
1964
2098
|
.default_stmt => |default_stmt| {
|
|
1965
2099
|
var sub = default_stmt.body;
|
|
@@ -1971,18 +2105,16 @@ fn transSwitchProngStmtInline(
|
|
|
1971
2105
|
const result = try t.transStmt(&block.base, sub);
|
|
1972
2106
|
assert(result.tag() != .declaration);
|
|
1973
2107
|
try block.statements.append(t.gpa, result);
|
|
1974
|
-
if (result.isNoreturn(
|
|
1975
|
-
},
|
|
1976
|
-
.compound_stmt => |compound_stmt| {
|
|
1977
|
-
const result = try t.transCompoundStmt(&block.base, compound_stmt);
|
|
1978
|
-
try block.statements.append(t.gpa, result);
|
|
1979
|
-
if (result.isNoreturn(true)) return;
|
|
2108
|
+
if (result.isNoreturn()) return;
|
|
1980
2109
|
},
|
|
1981
2110
|
else => {
|
|
1982
2111
|
const result = try t.transStmt(&block.base, stmt);
|
|
1983
2112
|
switch (result.tag()) {
|
|
1984
2113
|
.declaration, .empty_block => {},
|
|
1985
|
-
else =>
|
|
2114
|
+
else => {
|
|
2115
|
+
try block.statements.append(t.gpa, result);
|
|
2116
|
+
if (result.isNoreturn()) return;
|
|
2117
|
+
},
|
|
1986
2118
|
}
|
|
1987
2119
|
},
|
|
1988
2120
|
}
|
|
@@ -2015,7 +2147,14 @@ fn transExpr(t: *Translator, scope: *Scope, expr: Node.Index, used: ResultUsed)
|
|
|
2015
2147
|
break :res try ZigTag.deref.create(t.arena, try t.transExpr(scope, deref_expr.operand, .used));
|
|
2016
2148
|
},
|
|
2017
2149
|
.bool_not_expr => |bool_not_expr| try ZigTag.not.create(t.arena, try t.transBoolExpr(scope, bool_not_expr.operand)),
|
|
2018
|
-
.bit_not_expr => |bit_not_expr| try ZigTag.bit_not.create(t.arena,
|
|
2150
|
+
.bit_not_expr => |bit_not_expr| try ZigTag.bit_not.create(t.arena, op: {
|
|
2151
|
+
const operand = try t.transExpr(scope, bit_not_expr.operand, .used);
|
|
2152
|
+
if (!operand.isBoolRes()) break :op operand;
|
|
2153
|
+
|
|
2154
|
+
const casted = try ZigTag.int_from_bool.create(t.arena, operand);
|
|
2155
|
+
const ty = try t.transType(scope, bit_not_expr.qt, bit_not_expr.op_tok);
|
|
2156
|
+
break :op try ZigTag.as.create(t.arena, .{ .lhs = ty, .rhs = casted });
|
|
2157
|
+
}),
|
|
2019
2158
|
.plus_expr => |plus_expr| return t.transExpr(scope, plus_expr.operand, used),
|
|
2020
2159
|
.negate_expr => |negate_expr| res: {
|
|
2021
2160
|
const operand_qt = negate_expr.operand.qt(t.tree);
|
|
@@ -2109,8 +2248,8 @@ fn transExpr(t: *Translator, scope: *Scope, expr: Node.Index, used: ResultUsed)
|
|
|
2109
2248
|
.shl_expr => |shl_expr| try t.transShiftExpr(scope, shl_expr, .shl),
|
|
2110
2249
|
.shr_expr => |shr_expr| try t.transShiftExpr(scope, shr_expr, .shr),
|
|
2111
2250
|
|
|
2112
|
-
.member_access_expr => |member_access| try t.transMemberAccess(scope, .normal, member_access, null),
|
|
2113
|
-
.member_access_ptr_expr => |member_access| try t.transMemberAccess(scope, .ptr, member_access, null),
|
|
2251
|
+
.member_access_expr => |member_access| try t.transMemberAccess(scope, .normal, member_access, null, .accessor),
|
|
2252
|
+
.member_access_ptr_expr => |member_access| try t.transMemberAccess(scope, .ptr, member_access, null, .accessor),
|
|
2114
2253
|
.array_access_expr => |array_access| try t.transArrayAccess(scope, array_access, null),
|
|
2115
2254
|
|
|
2116
2255
|
.builtin_ref => unreachable,
|
|
@@ -2195,6 +2334,10 @@ fn transExpr(t: *Translator, scope: *Scope, expr: Node.Index, used: ResultUsed)
|
|
|
2195
2334
|
.builtin_convertvector => |convertvector| try t.transConvertvectorExpr(scope, convertvector),
|
|
2196
2335
|
.builtin_shufflevector => |shufflevector| try t.transShufflevectorExpr(scope, shufflevector),
|
|
2197
2336
|
|
|
2337
|
+
.builtin_va_arg_pack, .builtin_va_arg_pack_len => |va_arg_pack| {
|
|
2338
|
+
return t.fail(error.UnsupportedTranslation, va_arg_pack.builtin_tok, "TODO va arg pack", .{});
|
|
2339
|
+
},
|
|
2340
|
+
|
|
2198
2341
|
.compound_stmt,
|
|
2199
2342
|
.static_assert,
|
|
2200
2343
|
.return_stmt,
|
|
@@ -2293,6 +2436,12 @@ fn transBoolExpr(t: *Translator, scope: *Scope, expr: Node.Index) TransError!Zig
|
|
|
2293
2436
|
return t.finishBoolExpr(expr.qt(t.tree), maybe_bool_res);
|
|
2294
2437
|
}
|
|
2295
2438
|
|
|
2439
|
+
fn toNonBool(t: *Translator, node: ZigNode, qt: QualType) Error!ZigNode {
|
|
2440
|
+
if (!node.isBoolRes()) return node;
|
|
2441
|
+
if (qt.is(t.comp, .bool)) return node;
|
|
2442
|
+
return ZigTag.int_from_bool.create(t.arena, node);
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2296
2445
|
fn finishBoolExpr(t: *Translator, qt: QualType, node: ZigNode) TransError!ZigNode {
|
|
2297
2446
|
const sk = qt.scalarKind(t.comp);
|
|
2298
2447
|
if (sk == .bool) return node;
|
|
@@ -2385,8 +2534,22 @@ fn transCastExpr(
|
|
|
2385
2534
|
else => {},
|
|
2386
2535
|
}
|
|
2387
2536
|
|
|
2388
|
-
|
|
2389
|
-
|
|
2537
|
+
// Flexible array members are translated as member functions returning
|
|
2538
|
+
// [*c]T, so no address-of + @ptrCast wrapping is needed.
|
|
2539
|
+
flexible: {
|
|
2540
|
+
if (cast.operand.qt(t.tree).arrayLen(t.comp) == null) {
|
|
2541
|
+
return try t.transExpr(scope, cast.operand, used);
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
const member_index, const base_qt = switch (cast.operand.get(t.tree)) {
|
|
2545
|
+
.member_access_expr => |ma| .{ ma.member_index, ma.base.qt(t.tree) },
|
|
2546
|
+
.member_access_ptr_expr => |ma| .{ ma.member_index, ma.base.qt(t.tree).childType(t.comp) },
|
|
2547
|
+
else => break :flexible,
|
|
2548
|
+
};
|
|
2549
|
+
const record = base_qt.getRecord(t.comp) orelse break :flexible;
|
|
2550
|
+
if (member_index != record.fields.len - 1 and base_qt.base(t.comp).type != .@"union") break :flexible;
|
|
2551
|
+
const array_ty = record.fields[member_index].qt.get(t.comp, .array) orelse break :flexible;
|
|
2552
|
+
if (t.isFlexibleArrayLen(array_ty.len)) return try t.transExpr(scope, cast.operand, used);
|
|
2390
2553
|
}
|
|
2391
2554
|
|
|
2392
2555
|
const sub_expr_node = try t.transExpr(scope, cast.operand, .used);
|
|
@@ -2402,6 +2565,8 @@ fn transCastExpr(
|
|
|
2402
2565
|
.lhs = try ZigTag.type.create(t.arena, "usize"),
|
|
2403
2566
|
.rhs = try ZigTag.int_cast.create(t.arena, sub_expr_node),
|
|
2404
2567
|
});
|
|
2568
|
+
} else if (sub_expr_node.isBoolRes()) {
|
|
2569
|
+
sub_expr_node = try ZigTag.int_from_bool.create(t.arena, sub_expr_node);
|
|
2405
2570
|
}
|
|
2406
2571
|
break :int_to_pointer try ZigTag.ptr_from_int.create(t.arena, sub_expr_node);
|
|
2407
2572
|
},
|
|
@@ -2560,6 +2725,8 @@ fn transPointerCastExpr(t: *Translator, scope: *Scope, expr: Node.Index) TransEr
|
|
|
2560
2725
|
}
|
|
2561
2726
|
|
|
2562
2727
|
fn transDeclRefExpr(t: *Translator, scope: *Scope, decl_ref: Node.DeclRef) TransError!ZigNode {
|
|
2728
|
+
if (t.wip_var_inits.contains(decl_ref.decl)) return error.SelfReferential;
|
|
2729
|
+
|
|
2563
2730
|
const name = t.tree.tokSlice(decl_ref.name_tok);
|
|
2564
2731
|
const maybe_alias = scope.getAlias(name);
|
|
2565
2732
|
const mangled_name = maybe_alias orelse name;
|
|
@@ -2631,7 +2798,7 @@ fn transShiftExpr(t: *Translator, scope: *Scope, bin: Node.Binary, op_id: ZigTag
|
|
|
2631
2798
|
// lhs >> @intCast(rh)
|
|
2632
2799
|
const lhs = try t.transExpr(scope, bin.lhs, .used);
|
|
2633
2800
|
|
|
2634
|
-
const rhs = try t.
|
|
2801
|
+
const rhs = try t.transExpr(scope, bin.rhs, .used);
|
|
2635
2802
|
const rhs_casted = try ZigTag.int_cast.create(t.arena, rhs);
|
|
2636
2803
|
|
|
2637
2804
|
return t.createBinOpNode(op_id, lhs, rhs_casted);
|
|
@@ -2758,7 +2925,7 @@ fn transCommaExpr(t: *Translator, scope: *Scope, bin: Node.Binary, used: ResultU
|
|
|
2758
2925
|
const rhs = try t.transExprCoercing(&block_scope.base, bin.rhs, .used);
|
|
2759
2926
|
const break_node = try ZigTag.break_val.create(t.arena, .{
|
|
2760
2927
|
.label = block_scope.label,
|
|
2761
|
-
.val = rhs,
|
|
2928
|
+
.val = try t.toNonBool(rhs, bin.qt),
|
|
2762
2929
|
});
|
|
2763
2930
|
try block_scope.statements.append(t.gpa, break_node);
|
|
2764
2931
|
|
|
@@ -2768,14 +2935,10 @@ fn transCommaExpr(t: *Translator, scope: *Scope, bin: Node.Binary, used: ResultU
|
|
|
2768
2935
|
fn transAssignExpr(t: *Translator, scope: *Scope, bin: Node.Binary, used: ResultUsed) !ZigNode {
|
|
2769
2936
|
if (used == .unused) {
|
|
2770
2937
|
const lhs = try t.transExpr(scope, bin.lhs, .used);
|
|
2771
|
-
|
|
2938
|
+
const rhs = try t.transExprCoercing(scope, bin.rhs, .used);
|
|
2772
2939
|
|
|
2773
2940
|
const lhs_qt = bin.lhs.qt(t.tree);
|
|
2774
|
-
|
|
2775
|
-
rhs = try ZigTag.int_from_bool.create(t.arena, rhs);
|
|
2776
|
-
}
|
|
2777
|
-
|
|
2778
|
-
return t.createBinOpNode(.assign, lhs, rhs);
|
|
2941
|
+
return t.createBinOpNode(.assign, lhs, try t.toNonBool(rhs, lhs_qt));
|
|
2779
2942
|
}
|
|
2780
2943
|
|
|
2781
2944
|
var block_scope = try Scope.Block.init(t, scope, true);
|
|
@@ -2783,13 +2946,12 @@ fn transAssignExpr(t: *Translator, scope: *Scope, bin: Node.Binary, used: Result
|
|
|
2783
2946
|
|
|
2784
2947
|
const tmp = try block_scope.reserveMangledName("tmp");
|
|
2785
2948
|
|
|
2786
|
-
|
|
2949
|
+
const rhs = try t.transExpr(&block_scope.base, bin.rhs, .used);
|
|
2787
2950
|
const lhs_qt = bin.lhs.qt(t.tree);
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
const tmp_decl = try ZigTag.var_simple.create(t.arena, .{ .name = tmp, .init = rhs });
|
|
2951
|
+
const tmp_decl = try ZigTag.var_simple.create(t.arena, .{
|
|
2952
|
+
.name = tmp,
|
|
2953
|
+
.init = try t.toNonBool(rhs, lhs_qt),
|
|
2954
|
+
});
|
|
2793
2955
|
try block_scope.statements.append(t.gpa, tmp_decl);
|
|
2794
2956
|
|
|
2795
2957
|
const lhs = try t.transExprCoercing(&block_scope.base, bin.lhs, .used);
|
|
@@ -3040,6 +3202,7 @@ fn transMemberAccess(
|
|
|
3040
3202
|
kind: enum { normal, ptr },
|
|
3041
3203
|
member_access: Node.MemberAccess,
|
|
3042
3204
|
opt_base: ?ZigNode,
|
|
3205
|
+
flex_array_mode: enum { accessor, backing },
|
|
3043
3206
|
) TransError!ZigNode {
|
|
3044
3207
|
const base_info = switch (kind) {
|
|
3045
3208
|
.normal => member_access.base.qt(t.tree),
|
|
@@ -3068,8 +3231,14 @@ fn transMemberAccess(
|
|
|
3068
3231
|
// Flexible array members are translated as member functions.
|
|
3069
3232
|
if (member_access.member_index == record.fields.len - 1 or base_info.base(t.comp).type == .@"union") {
|
|
3070
3233
|
if (field.qt.get(t.comp, .array)) |array_ty| {
|
|
3071
|
-
if (
|
|
3072
|
-
|
|
3234
|
+
if (t.isFlexibleArrayLen(array_ty.len)) {
|
|
3235
|
+
switch (flex_array_mode) {
|
|
3236
|
+
.accessor => return ZigTag.call.create(t.arena, .{ .lhs = field_access, .args = &.{} }),
|
|
3237
|
+
.backing => {
|
|
3238
|
+
const backing_name = try std.fmt.allocPrint(t.arena, "_{s}", .{field_name});
|
|
3239
|
+
return ZigTag.field_access.create(t.arena, .{ .lhs = lhs, .field_name = backing_name });
|
|
3240
|
+
},
|
|
3241
|
+
}
|
|
3073
3242
|
}
|
|
3074
3243
|
}
|
|
3075
3244
|
}
|
|
@@ -3091,7 +3260,7 @@ fn transArrayAccess(t: *Translator, scope: *Scope, array_access: Node.ArrayAcces
|
|
|
3091
3260
|
const index = index: {
|
|
3092
3261
|
const index = try t.transExpr(scope, array_access.index, .used);
|
|
3093
3262
|
const index_qt = array_access.index.qt(t.tree);
|
|
3094
|
-
const maybe_bigger_than_usize = switch (index_qt.base(t.comp).type) {
|
|
3263
|
+
const maybe_bigger_than_usize = type: switch (index_qt.base(t.comp).type) {
|
|
3095
3264
|
.bool => {
|
|
3096
3265
|
break :index try ZigTag.int_from_bool.create(t.arena, index);
|
|
3097
3266
|
},
|
|
@@ -3100,6 +3269,7 @@ fn transArrayAccess(t: *Translator, scope: *Scope, array_access: Node.ArrayAcces
|
|
|
3100
3269
|
else => false,
|
|
3101
3270
|
},
|
|
3102
3271
|
.bit_int => |bit_int| bit_int.bits > t.comp.target.ptrBitWidth(),
|
|
3272
|
+
.@"enum" => |e| if (e.tag) |tag| continue :type tag.base(t.comp).type else false,
|
|
3103
3273
|
else => unreachable,
|
|
3104
3274
|
};
|
|
3105
3275
|
|
|
@@ -3158,7 +3328,10 @@ fn transMemberDesignator(t: *Translator, scope: *Scope, arg: Node.Index) TransEr
|
|
|
3158
3328
|
},
|
|
3159
3329
|
.member_access_expr => |access| {
|
|
3160
3330
|
const base = try t.transMemberDesignator(scope, access.base);
|
|
3161
|
-
|
|
3331
|
+
// In offsetof context, flexible array members must be accessed via
|
|
3332
|
+
// the backing field (`_name`) rather than the accessor function,
|
|
3333
|
+
// because you can't take the address of a function call result.
|
|
3334
|
+
return t.transMemberAccess(scope, .normal, access, base, .backing);
|
|
3162
3335
|
},
|
|
3163
3336
|
.cast => |cast| {
|
|
3164
3337
|
assert(cast.kind == .array_to_pointer);
|
|
@@ -3292,6 +3465,51 @@ fn transCall(
|
|
|
3292
3465
|
|
|
3293
3466
|
const SuppressCast = enum { with_as, no_as };
|
|
3294
3467
|
|
|
3468
|
+
/// Attempt to translate literal as the name of the simple macro
|
|
3469
|
+
/// it was expanded from.
|
|
3470
|
+
fn checkLiteralMacro(t: *Translator, tok: TokenIndex, used: ResultUsed) !?ZigNode {
|
|
3471
|
+
if (!t.keep_macro_literals) return null;
|
|
3472
|
+
const expansion_locs = t.pp.expansionSlice(tok);
|
|
3473
|
+
if (expansion_locs.len == 0) return null;
|
|
3474
|
+
|
|
3475
|
+
const last_expand = expansion_locs[0];
|
|
3476
|
+
const source = t.comp.getSource(last_expand.id);
|
|
3477
|
+
var tokenizer: aro.Tokenizer = .{
|
|
3478
|
+
.buf = source.buf,
|
|
3479
|
+
.langopts = t.comp.langopts,
|
|
3480
|
+
.source = last_expand.id,
|
|
3481
|
+
.index = last_expand.byte_offset,
|
|
3482
|
+
.splice_locs = &.{},
|
|
3483
|
+
};
|
|
3484
|
+
const name_tok = tokenizer.next();
|
|
3485
|
+
if (!name_tok.id.isMacroIdentifier()) return null;
|
|
3486
|
+
|
|
3487
|
+
const name = t.pp.tokSlice(name_tok);
|
|
3488
|
+
if (t.global_scope.containsNow(name)) return null;
|
|
3489
|
+
const macro = t.pp.defines.get(name) orelse return null;
|
|
3490
|
+
if (macro.is_func) return null;
|
|
3491
|
+
if (macro.isBuiltin()) return null;
|
|
3492
|
+
|
|
3493
|
+
var tok_count: u8 = 0;
|
|
3494
|
+
for (macro.tokens) |macro_tok| {
|
|
3495
|
+
switch (macro_tok.id) {
|
|
3496
|
+
.invalid => continue,
|
|
3497
|
+
.whitespace => continue,
|
|
3498
|
+
.comment => continue,
|
|
3499
|
+
.macro_ws => continue,
|
|
3500
|
+
else => {
|
|
3501
|
+
if (tok_count != 0) return null;
|
|
3502
|
+
tok_count += 1;
|
|
3503
|
+
},
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
|
|
3507
|
+
if (t.checkTranslatableMacro(macro.tokens, macro.params) != null) return null;
|
|
3508
|
+
|
|
3509
|
+
const ident = try ZigTag.identifier.create(t.arena, name);
|
|
3510
|
+
return try t.maybeSuppressResult(used, ident);
|
|
3511
|
+
}
|
|
3512
|
+
|
|
3295
3513
|
fn transIntLiteral(
|
|
3296
3514
|
t: *Translator,
|
|
3297
3515
|
scope: *Scope,
|
|
@@ -3299,6 +3517,7 @@ fn transIntLiteral(
|
|
|
3299
3517
|
used: ResultUsed,
|
|
3300
3518
|
suppress_as: SuppressCast,
|
|
3301
3519
|
) TransError!ZigNode {
|
|
3520
|
+
if (try t.checkLiteralMacro(literal_index.tok(t.tree), used)) |node| return node;
|
|
3302
3521
|
const val = t.tree.value_map.get(literal_index).?;
|
|
3303
3522
|
const int_lit_node = try t.createIntNode(val);
|
|
3304
3523
|
if (suppress_as == .no_as) {
|
|
@@ -3325,6 +3544,7 @@ fn transCharLiteral(
|
|
|
3325
3544
|
used: ResultUsed,
|
|
3326
3545
|
suppress_as: SuppressCast,
|
|
3327
3546
|
) TransError!ZigNode {
|
|
3547
|
+
if (try t.checkLiteralMacro(literal_index.tok(t.tree), used)) |node| return node;
|
|
3328
3548
|
const val = t.tree.value_map.get(literal_index).?;
|
|
3329
3549
|
const char_literal = literal_index.get(t.tree).char_literal;
|
|
3330
3550
|
const narrow = char_literal.kind == .ascii or char_literal.kind == .utf8;
|
|
@@ -3333,7 +3553,7 @@ fn transCharLiteral(
|
|
|
3333
3553
|
// e.g. 'abcd'
|
|
3334
3554
|
const int_value = val.toInt(u32, t.comp).?;
|
|
3335
3555
|
const int_lit_node = if (char_literal.kind == .ascii and int_value > 255)
|
|
3336
|
-
try t.createNumberNode(int_value
|
|
3556
|
+
try t.createNumberNode(int_value)
|
|
3337
3557
|
else
|
|
3338
3558
|
try t.createCharLiteralNode(narrow, int_value);
|
|
3339
3559
|
|
|
@@ -3357,12 +3577,16 @@ fn transFloatLiteral(
|
|
|
3357
3577
|
used: ResultUsed,
|
|
3358
3578
|
suppress_as: SuppressCast,
|
|
3359
3579
|
) TransError!ZigNode {
|
|
3580
|
+
if (try t.checkLiteralMacro(literal_index.tok(t.tree), used)) |node| return node;
|
|
3360
3581
|
const val = t.tree.value_map.get(literal_index).?;
|
|
3361
3582
|
const float_literal = literal_index.get(t.tree).float_literal;
|
|
3362
3583
|
|
|
3363
3584
|
var allocating: std.Io.Writer.Allocating = .init(t.gpa);
|
|
3364
3585
|
defer allocating.deinit();
|
|
3365
3586
|
_ = val.print(float_literal.qt, t.comp, &allocating.writer) catch return error.OutOfMemory;
|
|
3587
|
+
if (mem.findScalar(u8, allocating.written(), '.') == null) {
|
|
3588
|
+
allocating.writer.writeAll(".0") catch return error.OutOfMemory;
|
|
3589
|
+
}
|
|
3366
3590
|
|
|
3367
3591
|
const float_lit_node = try ZigTag.float_literal.create(t.arena, try t.arena.dupe(u8, allocating.written()));
|
|
3368
3592
|
if (suppress_as == .no_as) {
|
|
@@ -3588,7 +3812,7 @@ fn transArrayInit(
|
|
|
3588
3812
|
while (i < array_init.items.len) : (i += 1) {
|
|
3589
3813
|
if (array_init.items[i].get(t.tree) == .array_filler_expr) break;
|
|
3590
3814
|
const expr = try t.transExprCoercing(scope, array_init.items[i], .used);
|
|
3591
|
-
try val_list.append(t.gpa, expr);
|
|
3815
|
+
try val_list.append(t.gpa, try t.toNonBool(expr, array_item_qt));
|
|
3592
3816
|
}
|
|
3593
3817
|
const array_type = try ZigTag.array_type.create(t.arena, .{
|
|
3594
3818
|
.elem_type = array_item_type,
|
|
@@ -3638,7 +3862,7 @@ fn transUnionInit(
|
|
|
3638
3862
|
const field_init = try t.arena.create(ast.Payload.ContainerInit.Initializer);
|
|
3639
3863
|
field_init.* = .{
|
|
3640
3864
|
.name = field_name,
|
|
3641
|
-
.value = try t.transExprCoercing(scope, init_expr, .used),
|
|
3865
|
+
.value = try t.toNonBool(try t.transExprCoercing(scope, init_expr, .used), field.qt),
|
|
3642
3866
|
};
|
|
3643
3867
|
const container_init = try ZigTag.container_init.create(t.arena, .{
|
|
3644
3868
|
.lhs = union_type,
|
|
@@ -3669,7 +3893,7 @@ fn transStructInit(
|
|
|
3669
3893
|
}).? else field.name.lookup(t.comp);
|
|
3670
3894
|
init.* = .{
|
|
3671
3895
|
.name = field_name,
|
|
3672
|
-
.value = try t.transExprCoercing(scope, field_expr, .used),
|
|
3896
|
+
.value = try t.toNonBool(try t.transExprCoercing(scope, field_expr, .used), field.qt),
|
|
3673
3897
|
};
|
|
3674
3898
|
}
|
|
3675
3899
|
|
|
@@ -3766,7 +3990,7 @@ fn transConvertvectorExpr(
|
|
|
3766
3990
|
for (items, 0..dest_vec_ty.len) |*item, i| {
|
|
3767
3991
|
const value = try ZigTag.array_access.create(t.arena, .{
|
|
3768
3992
|
.lhs = tmp_ident,
|
|
3769
|
-
.rhs = try t.createNumberNode(i
|
|
3993
|
+
.rhs = try t.createNumberNode(i),
|
|
3770
3994
|
});
|
|
3771
3995
|
|
|
3772
3996
|
if (src_elem_sk == .float and dest_elem_sk == .float) {
|
|
@@ -3812,7 +4036,7 @@ fn transShufflevectorExpr(
|
|
|
3812
4036
|
const mask_len = shufflevector.indexes.len;
|
|
3813
4037
|
|
|
3814
4038
|
const mask_type = try ZigTag.vector.create(t.arena, .{
|
|
3815
|
-
.lhs = try t.createNumberNode(mask_len
|
|
4039
|
+
.lhs = try t.createNumberNode(mask_len),
|
|
3816
4040
|
.rhs = try ZigTag.type.create(t.arena, "i32"),
|
|
3817
4041
|
});
|
|
3818
4042
|
|
|
@@ -3875,23 +4099,16 @@ fn createIntNode(t: *Translator, int: aro.Value) !ZigNode {
|
|
|
3875
4099
|
big.positive = true;
|
|
3876
4100
|
|
|
3877
4101
|
const str = big.toStringAlloc(t.arena, 10, .lower) catch |err| switch (err) {
|
|
3878
|
-
error.OutOfMemory => return
|
|
4102
|
+
error.OutOfMemory => |e| return e,
|
|
3879
4103
|
};
|
|
3880
4104
|
const res = try ZigTag.integer_literal.create(t.arena, str);
|
|
3881
4105
|
if (is_negative) return ZigTag.negate.create(t.arena, res);
|
|
3882
4106
|
return res;
|
|
3883
4107
|
}
|
|
3884
4108
|
|
|
3885
|
-
fn createNumberNode(t: *Translator, num: anytype
|
|
3886
|
-
const
|
|
3887
|
-
|
|
3888
|
-
else => "{s}",
|
|
3889
|
-
};
|
|
3890
|
-
const str = try std.fmt.allocPrint(t.arena, fmt_s, .{num});
|
|
3891
|
-
if (num_kind == .float)
|
|
3892
|
-
return ZigTag.float_literal.create(t.arena, str)
|
|
3893
|
-
else
|
|
3894
|
-
return ZigTag.integer_literal.create(t.arena, str);
|
|
4109
|
+
fn createNumberNode(t: *Translator, num: anytype) !ZigNode {
|
|
4110
|
+
const str = try std.fmt.allocPrint(t.arena, "{d}", .{num});
|
|
4111
|
+
return ZigTag.integer_literal.create(t.arena, str);
|
|
3895
4112
|
}
|
|
3896
4113
|
|
|
3897
4114
|
fn createCharLiteralNode(t: *Translator, narrow: bool, val: u32) TransError!ZigNode {
|
|
@@ -3953,6 +4170,25 @@ fn vectorTypeInfo(t: *Translator, vec_node: ZigNode, field: []const u8) TransErr
|
|
|
3953
4170
|
return ZigTag.field_access.create(t.arena, .{ .lhs = vector_type_info, .field_name = field });
|
|
3954
4171
|
}
|
|
3955
4172
|
|
|
4173
|
+
/// Returns true if the given array length qualifies as a flexible array member
|
|
4174
|
+
/// under the current -fstrict-flex-arrays level.
|
|
4175
|
+
fn isFlexibleArrayLen(t: *const Translator, len: anytype) bool {
|
|
4176
|
+
return switch (t.strict_flex_arrays) {
|
|
4177
|
+
.@"0" => true,
|
|
4178
|
+
.@"1" => switch (len) {
|
|
4179
|
+
.incomplete => true,
|
|
4180
|
+
.fixed => |n| n <= 1,
|
|
4181
|
+
else => false,
|
|
4182
|
+
},
|
|
4183
|
+
.@"2" => switch (len) {
|
|
4184
|
+
.incomplete => true,
|
|
4185
|
+
.fixed => |n| n == 0,
|
|
4186
|
+
else => false,
|
|
4187
|
+
},
|
|
4188
|
+
.@"3" => len == .incomplete,
|
|
4189
|
+
};
|
|
4190
|
+
}
|
|
4191
|
+
|
|
3956
4192
|
/// Build a getter function for a flexible array field in a C record
|
|
3957
4193
|
/// e.g. `T items[]` or `T items[0]`. The generated function returns a [*c] pointer
|
|
3958
4194
|
/// to the flexible array with the correct const and volatile qualifiers
|
|
@@ -3961,7 +4197,13 @@ fn createFlexibleMemberFn(
|
|
|
3961
4197
|
member_name: []const u8,
|
|
3962
4198
|
field_name: []const u8,
|
|
3963
4199
|
) Error!ZigNode {
|
|
3964
|
-
|
|
4200
|
+
// Use `_self` instead of the conventional `self` to avoid the Zig error
|
|
4201
|
+
// "function parameter shadows declaration of 'self'".
|
|
4202
|
+
// `processContainerMemberFns` merges C functions matching a struct's name
|
|
4203
|
+
// prefix into the struct as `pub const` aliases (e.g. `foo_self()` becomes
|
|
4204
|
+
// `pub const self = __root.foo_self`). A parameter also named `self` would
|
|
4205
|
+
// then shadow that declaration, which Zig rejects.
|
|
4206
|
+
const self_param_name = "_self";
|
|
3965
4207
|
const self_param = try ZigTag.identifier.create(t.arena, self_param_name);
|
|
3966
4208
|
const self_type = try ZigTag.typeof.create(t.arena, self_param);
|
|
3967
4209
|
|