| author | |
| committer | |
| log | 699b6cdf01babd86d56206667a35491d2c4d00f1 |
| tree | ddf70f0d6282034497707a579197428740cb3b30 |
| parent | ec36b82d058b7e20101a2f55a7ec123077ce9b70 |
9 files changed, 697 insertions(+), 672 deletions(-)
lib/std/c.zig-1| ... | @@ -10,7 +10,6 @@ const page_size = std.mem.page_size; | ... | @@ -10,7 +10,6 @@ const page_size = std.mem.page_size; |
| 10 | pub const tokenizer = @import("c/tokenizer.zig"); | 10 | pub const tokenizer = @import("c/tokenizer.zig"); |
| 11 | pub const Token = tokenizer.Token; | 11 | pub const Token = tokenizer.Token; |
| 12 | pub const Tokenizer = tokenizer.Tokenizer; | 12 | pub const Tokenizer = tokenizer.Tokenizer; |
| 13 | pub const builtins = @import("c/builtins.zig"); | ||
| 14 | 13 | ||
| 15 | test { | 14 | test { |
| 16 | _ = tokenizer; | 15 | _ = tokenizer; |
lib/std/c/builtins.zig deleted-196| ... | @@ -1,196 +0,0 @@ | ||
| 1 | // SPDX-License-Identifier: MIT | ||
| 2 | // Copyright (c) 2015-2021 Zig Contributors | ||
| 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. | ||
| 4 | // The MIT license requires this copyright notice to be included in all copies | ||
| 5 | // and substantial portions of the software. | ||
| 6 | |||
| 7 | const std = @import("std"); | ||
| 8 | |||
| 9 | pub inline fn __builtin_bswap16(val: u16) u16 { | ||
| 10 | return @byteSwap(u16, val); | ||
| 11 | } | ||
| 12 | pub inline fn __builtin_bswap32(val: u32) u32 { | ||
| 13 | return @byteSwap(u32, val); | ||
| 14 | } | ||
| 15 | pub inline fn __builtin_bswap64(val: u64) u64 { | ||
| 16 | return @byteSwap(u64, val); | ||
| 17 | } | ||
| 18 | |||
| 19 | pub inline fn __builtin_signbit(val: f64) c_int { | ||
| 20 | return @boolToInt(std.math.signbit(val)); | ||
| 21 | } | ||
| 22 | pub inline fn __builtin_signbitf(val: f32) c_int { | ||
| 23 | return @boolToInt(std.math.signbit(val)); | ||
| 24 | } | ||
| 25 | |||
| 26 | pub inline fn __builtin_popcount(val: c_uint) c_int { | ||
| 27 | // popcount of a c_uint will never exceed the capacity of a c_int | ||
| 28 | @setRuntimeSafety(false); | ||
| 29 | return @bitCast(c_int, @as(c_uint, @popCount(c_uint, val))); | ||
| 30 | } | ||
| 31 | pub inline fn __builtin_ctz(val: c_uint) c_int { | ||
| 32 | // Returns the number of trailing 0-bits in val, starting at the least significant bit position. | ||
| 33 | // In C if `val` is 0, the result is undefined; in zig it's the number of bits in a c_uint | ||
| 34 | @setRuntimeSafety(false); | ||
| 35 | return @bitCast(c_int, @as(c_uint, @ctz(c_uint, val))); | ||
| 36 | } | ||
| 37 | pub inline fn __builtin_clz(val: c_uint) c_int { | ||
| 38 | // Returns the number of leading 0-bits in x, starting at the most significant bit position. | ||
| 39 | // In C if `val` is 0, the result is undefined; in zig it's the number of bits in a c_uint | ||
| 40 | @setRuntimeSafety(false); | ||
| 41 | return @bitCast(c_int, @as(c_uint, @clz(c_uint, val))); | ||
| 42 | } | ||
| 43 | |||
| 44 | pub inline fn __builtin_sqrt(val: f64) f64 { | ||
| 45 | return @sqrt(val); | ||
| 46 | } | ||
| 47 | pub inline fn __builtin_sqrtf(val: f32) f32 { | ||
| 48 | return @sqrt(val); | ||
| 49 | } | ||
| 50 | |||
| 51 | pub inline fn __builtin_sin(val: f64) f64 { | ||
| 52 | return @sin(val); | ||
| 53 | } | ||
| 54 | pub inline fn __builtin_sinf(val: f32) f32 { | ||
| 55 | return @sin(val); | ||
| 56 | } | ||
| 57 | pub inline fn __builtin_cos(val: f64) f64 { | ||
| 58 | return @cos(val); | ||
| 59 | } | ||
| 60 | pub inline fn __builtin_cosf(val: f32) f32 { | ||
| 61 | return @cos(val); | ||
| 62 | } | ||
| 63 | |||
| 64 | pub inline fn __builtin_exp(val: f64) f64 { | ||
| 65 | return @exp(val); | ||
| 66 | } | ||
| 67 | pub inline fn __builtin_expf(val: f32) f32 { | ||
| 68 | return @exp(val); | ||
| 69 | } | ||
| 70 | pub inline fn __builtin_exp2(val: f64) f64 { | ||
| 71 | return @exp2(val); | ||
| 72 | } | ||
| 73 | pub inline fn __builtin_exp2f(val: f32) f32 { | ||
| 74 | return @exp2(val); | ||
| 75 | } | ||
| 76 | pub inline fn __builtin_log(val: f64) f64 { | ||
| 77 | return @log(val); | ||
| 78 | } | ||
| 79 | pub inline fn __builtin_logf(val: f32) f32 { | ||
| 80 | return @log(val); | ||
| 81 | } | ||
| 82 | pub inline fn __builtin_log2(val: f64) f64 { | ||
| 83 | return @log2(val); | ||
| 84 | } | ||
| 85 | pub inline fn __builtin_log2f(val: f32) f32 { | ||
| 86 | return @log2(val); | ||
| 87 | } | ||
| 88 | pub inline fn __builtin_log10(val: f64) f64 { | ||
| 89 | return @log10(val); | ||
| 90 | } | ||
| 91 | pub inline fn __builtin_log10f(val: f32) f32 { | ||
| 92 | return @log10(val); | ||
| 93 | } | ||
| 94 | |||
| 95 | // Standard C Library bug: The absolute value of the most negative integer remains negative. | ||
| 96 | pub inline fn __builtin_abs(val: c_int) c_int { | ||
| 97 | return std.math.absInt(val) catch std.math.minInt(c_int); | ||
| 98 | } | ||
| 99 | pub inline fn __builtin_fabs(val: f64) f64 { | ||
| 100 | return @fabs(val); | ||
| 101 | } | ||
| 102 | pub inline fn __builtin_fabsf(val: f32) f32 { | ||
| 103 | return @fabs(val); | ||
| 104 | } | ||
| 105 | |||
| 106 | pub inline fn __builtin_floor(val: f64) f64 { | ||
| 107 | return @floor(val); | ||
| 108 | } | ||
| 109 | pub inline fn __builtin_floorf(val: f32) f32 { | ||
| 110 | return @floor(val); | ||
| 111 | } | ||
| 112 | pub inline fn __builtin_ceil(val: f64) f64 { | ||
| 113 | return @ceil(val); | ||
| 114 | } | ||
| 115 | pub inline fn __builtin_ceilf(val: f32) f32 { | ||
| 116 | return @ceil(val); | ||
| 117 | } | ||
| 118 | pub inline fn __builtin_trunc(val: f64) f64 { | ||
| 119 | return @trunc(val); | ||
| 120 | } | ||
| 121 | pub inline fn __builtin_truncf(val: f32) f32 { | ||
| 122 | return @trunc(val); | ||
| 123 | } | ||
| 124 | pub inline fn __builtin_round(val: f64) f64 { | ||
| 125 | return @round(val); | ||
| 126 | } | ||
| 127 | pub inline fn __builtin_roundf(val: f32) f32 { | ||
| 128 | return @round(val); | ||
| 129 | } | ||
| 130 | |||
| 131 | pub inline fn __builtin_strlen(s: [*c]const u8) usize { | ||
| 132 | return std.mem.lenZ(s); | ||
| 133 | } | ||
| 134 | pub inline fn __builtin_strcmp(s1: [*c]const u8, s2: [*c]const u8) c_int { | ||
| 135 | return @as(c_int, std.cstr.cmp(s1, s2)); | ||
| 136 | } | ||
| 137 | |||
| 138 | pub inline fn __builtin_object_size(ptr: ?*const c_void, ty: c_int) usize { | ||
| 139 | // clang semantics match gcc's: https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html | ||
| 140 | // If it is not possible to determine which objects ptr points to at compile time, | ||
| 141 | // __builtin_object_size should return (size_t) -1 for type 0 or 1 and (size_t) 0 | ||
| 142 | // for type 2 or 3. | ||
| 143 | if (ty == 0 or ty == 1) return @bitCast(usize, -@as(isize, 1)); | ||
| 144 | if (ty == 2 or ty == 3) return 0; | ||
| 145 | unreachable; | ||
| 146 | } | ||
| 147 | |||
| 148 | pub inline fn __builtin___memset_chk( | ||
| 149 | dst: ?*c_void, | ||
| 150 | val: c_int, | ||
| 151 | len: usize, | ||
| 152 | remaining: usize, | ||
| 153 | ) ?*c_void { | ||
| 154 | if (len > remaining) @panic("std.c.builtins.memset_chk called with len > remaining"); | ||
| 155 | return __builtin_memset(dst, val, len); | ||
| 156 | } | ||
| 157 | |||
| 158 | pub inline fn __builtin_memset(dst: ?*c_void, val: c_int, len: usize) ?*c_void { | ||
| 159 | const dst_cast = @ptrCast([*c]u8, dst); | ||
| 160 | @memset(dst_cast, @bitCast(u8, @truncate(i8, val)), len); | ||
| 161 | return dst; | ||
| 162 | } | ||
| 163 | |||
| 164 | pub inline fn __builtin___memcpy_chk( | ||
| 165 | noalias dst: ?*c_void, | ||
| 166 | noalias src: ?*const c_void, | ||
| 167 | len: usize, | ||
| 168 | remaining: usize, | ||
| 169 | ) ?*c_void { | ||
| 170 | if (len > remaining) @panic("std.c.builtins.memcpy_chk called with len > remaining"); | ||
| 171 | return __builtin_memcpy(dst, src, len); | ||
| 172 | } | ||
| 173 | |||
| 174 | pub inline fn __builtin_memcpy( | ||
| 175 | noalias dst: ?*c_void, | ||
| 176 | noalias src: ?*const c_void, | ||
| 177 | len: usize, | ||
| 178 | ) ?*c_void { | ||
| 179 | const dst_cast = @ptrCast([*c]u8, dst); | ||
| 180 | const src_cast = @ptrCast([*c]const u8, src); | ||
| 181 | |||
| 182 | @memcpy(dst_cast, src_cast, len); | ||
| 183 | return dst; | ||
| 184 | } | ||
| 185 | |||
| 186 | /// The return value of __builtin_expect is `expr`. `c` is the expected value | ||
| 187 | /// of `expr` and is used as a hint to the compiler in C. Here it is unused. | ||
| 188 | pub inline fn __builtin_expect(expr: c_long, c: c_long) c_long { | ||
| 189 | return expr; | ||
| 190 | } | ||
| 191 | |||
| 192 | // __builtin_alloca_with_align is not currently implemented. | ||
| 193 | // It is used in a run-translated-c test and a test-translate-c test to ensure that non-implemented | ||
| 194 | // builtins are correctly demoted. If you implement __builtin_alloca_with_align, please update the | ||
| 195 | // run-translated-c test and the test-translate-c test to use a different non-implemented builtin. | ||
| 196 | // pub fn __builtin_alloca_with_align(size: usize, alignment: usize) callconv(.Inline) *c_void {} | ||
lib/std/meta.zig-376| ... | @@ -884,319 +884,6 @@ pub fn Vector(comptime len: u32, comptime child: type) type { | ... | @@ -884,319 +884,6 @@ pub fn Vector(comptime len: u32, comptime child: type) type { |
| 884 | }); | 884 | }); |
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | /// Given a type and value, cast the value to the type as c would. | ||
| 888 | /// This is for translate-c and is not intended for general use. | ||
| 889 | pub fn cast(comptime DestType: type, target: anytype) DestType { | ||
| 890 | // this function should behave like transCCast in translate-c, except it's for macros and enums | ||
| 891 | const SourceType = @TypeOf(target); | ||
| 892 | switch (@typeInfo(DestType)) { | ||
| 893 | .Pointer => return castToPtr(DestType, SourceType, target), | ||
| 894 | .Optional => |dest_opt| { | ||
| 895 | if (@typeInfo(dest_opt.child) == .Pointer) { | ||
| 896 | return castToPtr(DestType, SourceType, target); | ||
| 897 | } | ||
| 898 | }, | ||
| 899 | .Enum => |enum_type| { | ||
| 900 | if (@typeInfo(SourceType) == .Int or @typeInfo(SourceType) == .ComptimeInt) { | ||
| 901 | const intermediate = cast(enum_type.tag_type, target); | ||
| 902 | return @intToEnum(DestType, intermediate); | ||
| 903 | } | ||
| 904 | }, | ||
| 905 | .Int => { | ||
| 906 | switch (@typeInfo(SourceType)) { | ||
| 907 | .Pointer => { | ||
| 908 | return castInt(DestType, @ptrToInt(target)); | ||
| 909 | }, | ||
| 910 | .Optional => |opt| { | ||
| 911 | if (@typeInfo(opt.child) == .Pointer) { | ||
| 912 | return castInt(DestType, @ptrToInt(target)); | ||
| 913 | } | ||
| 914 | }, | ||
| 915 | .Enum => { | ||
| 916 | return castInt(DestType, @enumToInt(target)); | ||
| 917 | }, | ||
| 918 | .Int => { | ||
| 919 | return castInt(DestType, target); | ||
| 920 | }, | ||
| 921 | else => {}, | ||
| 922 | } | ||
| 923 | }, | ||
| 924 | else => {}, | ||
| 925 | } | ||
| 926 | return @as(DestType, target); | ||
| 927 | } | ||
| 928 | |||
| 929 | fn castInt(comptime DestType: type, target: anytype) DestType { | ||
| 930 | const dest = @typeInfo(DestType).Int; | ||
| 931 | const source = @typeInfo(@TypeOf(target)).Int; | ||
| 932 | |||
| 933 | if (dest.bits < source.bits) | ||
| 934 | return @bitCast(DestType, @truncate(Int(source.signedness, dest.bits), target)) | ||
| 935 | else | ||
| 936 | return @bitCast(DestType, @as(Int(source.signedness, dest.bits), target)); | ||
| 937 | } | ||
| 938 | |||
| 939 | fn castPtr(comptime DestType: type, target: anytype) DestType { | ||
| 940 | const dest = ptrInfo(DestType); | ||
| 941 | const source = ptrInfo(@TypeOf(target)); | ||
| 942 | |||
| 943 | if (source.is_const and !dest.is_const or source.is_volatile and !dest.is_volatile) | ||
| 944 | return @intToPtr(DestType, @ptrToInt(target)) | ||
| 945 | else if (@typeInfo(dest.child) == .Opaque) | ||
| 946 | // dest.alignment would error out | ||
| 947 | return @ptrCast(DestType, target) | ||
| 948 | else | ||
| 949 | return @ptrCast(DestType, @alignCast(dest.alignment, target)); | ||
| 950 | } | ||
| 951 | |||
| 952 | fn castToPtr(comptime DestType: type, comptime SourceType: type, target: anytype) DestType { | ||
| 953 | switch (@typeInfo(SourceType)) { | ||
| 954 | .Int => { | ||
| 955 | return @intToPtr(DestType, castInt(usize, target)); | ||
| 956 | }, | ||
| 957 | .ComptimeInt => { | ||
| 958 | if (target < 0) | ||
| 959 | return @intToPtr(DestType, @bitCast(usize, @intCast(isize, target))) | ||
| 960 | else | ||
| 961 | return @intToPtr(DestType, @intCast(usize, target)); | ||
| 962 | }, | ||
| 963 | .Pointer => { | ||
| 964 | return castPtr(DestType, target); | ||
| 965 | }, | ||
| 966 | .Optional => |target_opt| { | ||
| 967 | if (@typeInfo(target_opt.child) == .Pointer) { | ||
| 968 | return castPtr(DestType, target); | ||
| 969 | } | ||
| 970 | }, | ||
| 971 | else => {}, | ||
| 972 | } | ||
| 973 | return @as(DestType, target); | ||
| 974 | } | ||
| 975 | |||
| 976 | fn ptrInfo(comptime PtrType: type) TypeInfo.Pointer { | ||
| 977 | return switch (@typeInfo(PtrType)) { | ||
| 978 | .Optional => |opt_info| @typeInfo(opt_info.child).Pointer, | ||
| 979 | .Pointer => |ptr_info| ptr_info, | ||
| 980 | else => unreachable, | ||
| 981 | }; | ||
| 982 | } | ||
| 983 | |||
| 984 | test "std.meta.cast" { | ||
| 985 | const E = enum(u2) { | ||
| 986 | Zero, | ||
| 987 | One, | ||
| 988 | Two, | ||
| 989 | }; | ||
| 990 | |||
| 991 | var i = @as(i64, 10); | ||
| 992 | |||
| 993 | try testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16)); | ||
| 994 | try testing.expect(cast(*u64, &i).* == @as(u64, 10)); | ||
| 995 | try testing.expect(cast(*i64, @as(?*align(1) i64, &i)) == &i); | ||
| 996 | |||
| 997 | try testing.expect(cast(?*u8, 2) == @intToPtr(*u8, 2)); | ||
| 998 | try testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i); | ||
| 999 | try testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i); | ||
| 1000 | |||
| 1001 | try testing.expect(cast(E, 1) == .One); | ||
| 1002 | |||
| 1003 | try testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4))); | ||
| 1004 | try testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4))); | ||
| 1005 | try testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10))); | ||
| 1006 | try testing.expectEqual(@as(u8, 2), cast(u8, E.Two)); | ||
| 1007 | |||
| 1008 | try testing.expectEqual(@bitCast(i32, @as(u32, 0x8000_0000)), cast(i32, @as(u32, 0x8000_0000))); | ||
| 1009 | |||
| 1010 | try testing.expectEqual(@intToPtr(*u8, 2), cast(*u8, @intToPtr(*const u8, 2))); | ||
| 1011 | try testing.expectEqual(@intToPtr(*u8, 2), cast(*u8, @intToPtr(*volatile u8, 2))); | ||
| 1012 | |||
| 1013 | try testing.expectEqual(@intToPtr(?*c_void, 2), cast(?*c_void, @intToPtr(*u8, 2))); | ||
| 1014 | |||
| 1015 | const C_ENUM = enum(c_int) { | ||
| 1016 | A = 0, | ||
| 1017 | B, | ||
| 1018 | C, | ||
| 1019 | _, | ||
| 1020 | }; | ||
| 1021 | try testing.expectEqual(cast(C_ENUM, @as(i64, -1)), @intToEnum(C_ENUM, -1)); | ||
| 1022 | try testing.expectEqual(cast(C_ENUM, @as(i8, 1)), .B); | ||
| 1023 | try testing.expectEqual(cast(C_ENUM, @as(u64, 1)), .B); | ||
| 1024 | try testing.expectEqual(cast(C_ENUM, @as(u64, 42)), @intToEnum(C_ENUM, 42)); | ||
| 1025 | |||
| 1026 | var foo: c_int = -1; | ||
| 1027 | try testing.expect(cast(*c_void, -1) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)))); | ||
| 1028 | try testing.expect(cast(*c_void, foo) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)))); | ||
| 1029 | try testing.expect(cast(?*c_void, -1) == @intToPtr(?*c_void, @bitCast(usize, @as(isize, -1)))); | ||
| 1030 | try testing.expect(cast(?*c_void, foo) == @intToPtr(?*c_void, @bitCast(usize, @as(isize, -1)))); | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | /// Given a value returns its size as C's sizeof operator would. | ||
| 1034 | /// This is for translate-c and is not intended for general use. | ||
| 1035 | pub fn sizeof(target: anytype) usize { | ||
| 1036 | const T: type = if (@TypeOf(target) == type) target else @TypeOf(target); | ||
| 1037 | switch (@typeInfo(T)) { | ||
| 1038 | .Float, .Int, .Struct, .Union, .Enum, .Array, .Bool, .Vector => return @sizeOf(T), | ||
| 1039 | .Fn => { | ||
| 1040 | // sizeof(main) returns 1, sizeof(&main) returns pointer size. | ||
| 1041 | // We cannot distinguish those types in Zig, so use pointer size. | ||
| 1042 | return @sizeOf(T); | ||
| 1043 | }, | ||
| 1044 | .Null => return @sizeOf(*c_void), | ||
| 1045 | .Void => { | ||
| 1046 | // Note: sizeof(void) is 1 on clang/gcc and 0 on MSVC. | ||
| 1047 | return 1; | ||
| 1048 | }, | ||
| 1049 | .Opaque => { | ||
| 1050 | if (T == c_void) { | ||
| 1051 | // Note: sizeof(void) is 1 on clang/gcc and 0 on MSVC. | ||
| 1052 | return 1; | ||
| 1053 | } else { | ||
| 1054 | @compileError("Cannot use C sizeof on opaque type " ++ @typeName(T)); | ||
| 1055 | } | ||
| 1056 | }, | ||
| 1057 | .Optional => |opt| { | ||
| 1058 | if (@typeInfo(opt.child) == .Pointer) { | ||
| 1059 | return sizeof(opt.child); | ||
| 1060 | } else { | ||
| 1061 | @compileError("Cannot use C sizeof on non-pointer optional " ++ @typeName(T)); | ||
| 1062 | } | ||
| 1063 | }, | ||
| 1064 | .Pointer => |ptr| { | ||
| 1065 | if (ptr.size == .Slice) { | ||
| 1066 | @compileError("Cannot use C sizeof on slice type " ++ @typeName(T)); | ||
| 1067 | } | ||
| 1068 | // for strings, sizeof("a") returns 2. | ||
| 1069 | // normal pointer decay scenarios from C are handled | ||
| 1070 | // in the .Array case above, but strings remain literals | ||
| 1071 | // and are therefore always pointers, so they need to be | ||
| 1072 | // specially handled here. | ||
| 1073 | if (ptr.size == .One and ptr.is_const and @typeInfo(ptr.child) == .Array) { | ||
| 1074 | const array_info = @typeInfo(ptr.child).Array; | ||
| 1075 | if ((array_info.child == u8 or array_info.child == u16) and | ||
| 1076 | array_info.sentinel != null and | ||
| 1077 | array_info.sentinel.? == 0) | ||
| 1078 | { | ||
| 1079 | // length of the string plus one for the null terminator. | ||
| 1080 | return (array_info.len + 1) * @sizeOf(array_info.child); | ||
| 1081 | } | ||
| 1082 | } | ||
| 1083 | // When zero sized pointers are removed, this case will no | ||
| 1084 | // longer be reachable and can be deleted. | ||
| 1085 | if (@sizeOf(T) == 0) { | ||
| 1086 | return @sizeOf(*c_void); | ||
| 1087 | } | ||
| 1088 | return @sizeOf(T); | ||
| 1089 | }, | ||
| 1090 | .ComptimeFloat => return @sizeOf(f64), // TODO c_double #3999 | ||
| 1091 | .ComptimeInt => { | ||
| 1092 | // TODO to get the correct result we have to translate | ||
| 1093 | // `1073741824 * 4` as `int(1073741824) *% int(4)` since | ||
| 1094 | // sizeof(1073741824 * 4) != sizeof(4294967296). | ||
| 1095 | |||
| 1096 | // TODO test if target fits in int, long or long long | ||
| 1097 | return @sizeOf(c_int); | ||
| 1098 | }, | ||
| 1099 | else => @compileError("std.meta.sizeof does not support type " ++ @typeName(T)), | ||
| 1100 | } | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | test "sizeof" { | ||
| 1104 | const E = enum(c_int) { One, _ }; | ||
| 1105 | const S = extern struct { a: u32 }; | ||
| 1106 | |||
| 1107 | const ptr_size = @sizeOf(*c_void); | ||
| 1108 | |||
| 1109 | try testing.expect(sizeof(u32) == 4); | ||
| 1110 | try testing.expect(sizeof(@as(u32, 2)) == 4); | ||
| 1111 | try testing.expect(sizeof(2) == @sizeOf(c_int)); | ||
| 1112 | |||
| 1113 | try testing.expect(sizeof(2.0) == @sizeOf(f64)); | ||
| 1114 | |||
| 1115 | try testing.expect(sizeof(E) == @sizeOf(c_int)); | ||
| 1116 | try testing.expect(sizeof(E.One) == @sizeOf(c_int)); | ||
| 1117 | |||
| 1118 | try testing.expect(sizeof(S) == 4); | ||
| 1119 | |||
| 1120 | try testing.expect(sizeof([_]u32{ 4, 5, 6 }) == 12); | ||
| 1121 | try testing.expect(sizeof([3]u32) == 12); | ||
| 1122 | try testing.expect(sizeof([3:0]u32) == 16); | ||
| 1123 | try testing.expect(sizeof(&[_]u32{ 4, 5, 6 }) == ptr_size); | ||
| 1124 | |||
| 1125 | try testing.expect(sizeof(*u32) == ptr_size); | ||
| 1126 | try testing.expect(sizeof([*]u32) == ptr_size); | ||
| 1127 | try testing.expect(sizeof([*c]u32) == ptr_size); | ||
| 1128 | try testing.expect(sizeof(?*u32) == ptr_size); | ||
| 1129 | try testing.expect(sizeof(?[*]u32) == ptr_size); | ||
| 1130 | try testing.expect(sizeof(*c_void) == ptr_size); | ||
| 1131 | try testing.expect(sizeof(*void) == ptr_size); | ||
| 1132 | try testing.expect(sizeof(null) == ptr_size); | ||
| 1133 | |||
| 1134 | try testing.expect(sizeof("foobar") == 7); | ||
| 1135 | try testing.expect(sizeof(&[_:0]u16{ 'f', 'o', 'o', 'b', 'a', 'r' }) == 14); | ||
| 1136 | try testing.expect(sizeof(*const [4:0]u8) == 5); | ||
| 1137 | try testing.expect(sizeof(*[4:0]u8) == ptr_size); | ||
| 1138 | try testing.expect(sizeof([*]const [4:0]u8) == ptr_size); | ||
| 1139 | try testing.expect(sizeof(*const *const [4:0]u8) == ptr_size); | ||
| 1140 | try testing.expect(sizeof(*const [4]u8) == ptr_size); | ||
| 1141 | |||
| 1142 | try testing.expect(sizeof(sizeof) == @sizeOf(@TypeOf(sizeof))); | ||
| 1143 | |||
| 1144 | try testing.expect(sizeof(void) == 1); | ||
| 1145 | try testing.expect(sizeof(c_void) == 1); | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | pub const CIntLiteralRadix = enum { decimal, octal, hexadecimal }; | ||
| 1149 | |||
| 1150 | fn PromoteIntLiteralReturnType(comptime SuffixType: type, comptime number: comptime_int, comptime radix: CIntLiteralRadix) type { | ||
| 1151 | const signed_decimal = [_]type{ c_int, c_long, c_longlong }; | ||
| 1152 | const signed_oct_hex = [_]type{ c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong }; | ||
| 1153 | const unsigned = [_]type{ c_uint, c_ulong, c_ulonglong }; | ||
| 1154 | |||
| 1155 | const list: []const type = if (@typeInfo(SuffixType).Int.signedness == .unsigned) | ||
| 1156 | &unsigned | ||
| 1157 | else if (radix == .decimal) | ||
| 1158 | &signed_decimal | ||
| 1159 | else | ||
| 1160 | &signed_oct_hex; | ||
| 1161 | |||
| 1162 | var pos = mem.indexOfScalar(type, list, SuffixType).?; | ||
| 1163 | |||
| 1164 | while (pos < list.len) : (pos += 1) { | ||
| 1165 | if (number >= math.minInt(list[pos]) and number <= math.maxInt(list[pos])) { | ||
| 1166 | return list[pos]; | ||
| 1167 | } | ||
| 1168 | } | ||
| 1169 | @compileError("Integer literal is too large"); | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | /// Promote the type of an integer literal until it fits as C would. | ||
| 1173 | /// This is for translate-c and is not intended for general use. | ||
| 1174 | pub fn promoteIntLiteral( | ||
| 1175 | comptime SuffixType: type, | ||
| 1176 | comptime number: comptime_int, | ||
| 1177 | comptime radix: CIntLiteralRadix, | ||
| 1178 | ) PromoteIntLiteralReturnType(SuffixType, number, radix) { | ||
| 1179 | return number; | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | test "promoteIntLiteral" { | ||
| 1183 | const signed_hex = promoteIntLiteral(c_int, math.maxInt(c_int) + 1, .hexadecimal); | ||
| 1184 | try testing.expectEqual(c_uint, @TypeOf(signed_hex)); | ||
| 1185 | |||
| 1186 | if (math.maxInt(c_longlong) == math.maxInt(c_int)) return; | ||
| 1187 | |||
| 1188 | const signed_decimal = promoteIntLiteral(c_int, math.maxInt(c_int) + 1, .decimal); | ||
| 1189 | const unsigned = promoteIntLiteral(c_uint, math.maxInt(c_uint) + 1, .hexadecimal); | ||
| 1190 | |||
| 1191 | if (math.maxInt(c_long) > math.maxInt(c_int)) { | ||
| 1192 | try testing.expectEqual(c_long, @TypeOf(signed_decimal)); | ||
| 1193 | try testing.expectEqual(c_ulong, @TypeOf(unsigned)); | ||
| 1194 | } else { | ||
| 1195 | try testing.expectEqual(c_longlong, @TypeOf(signed_decimal)); | ||
| 1196 | try testing.expectEqual(c_ulonglong, @TypeOf(unsigned)); | ||
| 1197 | } | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | /// For a given function type, returns a tuple type which fields will | 887 | /// For a given function type, returns a tuple type which fields will |
| 1201 | /// correspond to the argument types. | 888 | /// correspond to the argument types. |
| 1202 | /// | 889 | /// |
| ... | @@ -1316,38 +1003,6 @@ pub fn globalOption(comptime name: []const u8, comptime T: type) ?T { | ... | @@ -1316,38 +1003,6 @@ pub fn globalOption(comptime name: []const u8, comptime T: type) ?T { |
| 1316 | return @as(T, @field(root, name)); | 1003 | return @as(T, @field(root, name)); |
| 1317 | } | 1004 | } |
| 1318 | 1005 | ||
| 1319 | /// This function is for translate-c and is not intended for general use. | ||
| 1320 | /// Convert from clang __builtin_shufflevector index to Zig @shuffle index | ||
| 1321 | /// clang requires __builtin_shufflevector index arguments to be integer constants. | ||
| 1322 | /// negative values for `this_index` indicate "don't care" so we arbitrarily choose 0 | ||
| 1323 | /// clang enforces that `this_index` is less than the total number of vector elements | ||
| 1324 | /// See https://ziglang.org/documentation/master/#shuffle | ||
| 1325 | /// See https://clang.llvm.org/docs/LanguageExtensions.html#langext-builtin-shufflevector | ||
| 1326 | pub fn shuffleVectorIndex(comptime this_index: c_int, comptime source_vector_len: usize) i32 { | ||
| 1327 | if (this_index <= 0) return 0; | ||
| 1328 | |||
| 1329 | const positive_index = @intCast(usize, this_index); | ||
| 1330 | if (positive_index < source_vector_len) return @intCast(i32, this_index); | ||
| 1331 | const b_index = positive_index - source_vector_len; | ||
| 1332 | return ~@intCast(i32, b_index); | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | test "shuffleVectorIndex" { | ||
| 1336 | const vector_len: usize = 4; | ||
| 1337 | |||
| 1338 | try testing.expect(shuffleVectorIndex(-1, vector_len) == 0); | ||
| 1339 | |||
| 1340 | try testing.expect(shuffleVectorIndex(0, vector_len) == 0); | ||
| 1341 | try testing.expect(shuffleVectorIndex(1, vector_len) == 1); | ||
| 1342 | try testing.expect(shuffleVectorIndex(2, vector_len) == 2); | ||
| 1343 | try testing.expect(shuffleVectorIndex(3, vector_len) == 3); | ||
| 1344 | |||
| 1345 | try testing.expect(shuffleVectorIndex(4, vector_len) == -1); | ||
| 1346 | try testing.expect(shuffleVectorIndex(5, vector_len) == -2); | ||
| 1347 | try testing.expect(shuffleVectorIndex(6, vector_len) == -3); | ||
| 1348 | try testing.expect(shuffleVectorIndex(7, vector_len) == -4); | ||
| 1349 | } | ||
| 1350 | |||
| 1351 | /// Returns whether `error_union` contains an error. | 1006 | /// Returns whether `error_union` contains an error. |
| 1352 | pub fn isError(error_union: anytype) bool { | 1007 | pub fn isError(error_union: anytype) bool { |
| 1353 | return if (error_union) |_| false else |_| true; | 1008 | return if (error_union) |_| false else |_| true; |
| ... | @@ -1357,34 +1012,3 @@ test "isError" { | ... | @@ -1357,34 +1012,3 @@ test "isError" { |
| 1357 | try std.testing.expect(isError(math.absInt(@as(i8, -128)))); | 1012 | try std.testing.expect(isError(math.absInt(@as(i8, -128)))); |
| 1358 | try std.testing.expect(!isError(math.absInt(@as(i8, -127)))); | 1013 | try std.testing.expect(!isError(math.absInt(@as(i8, -127)))); |
| 1359 | } | 1014 | } |
| 1360 | |||
| 1361 | /// This function is for translate-c and is not intended for general use. | ||
| 1362 | /// Constructs a [*c] pointer with the const and volatile annotations | ||
| 1363 | /// from SelfType for pointing to a C flexible array of ElementType. | ||
| 1364 | pub fn FlexibleArrayType(comptime SelfType: type, ElementType: type) type { | ||
| 1365 | switch (@typeInfo(SelfType)) { | ||
| 1366 | .Pointer => |ptr| { | ||
| 1367 | return @Type(TypeInfo{ .Pointer = .{ | ||
| 1368 | .size = .C, | ||
| 1369 | .is_const = ptr.is_const, | ||
| 1370 | .is_volatile = ptr.is_volatile, | ||
| 1371 | .alignment = @alignOf(ElementType), | ||
| 1372 | .child = ElementType, | ||
| 1373 | .is_allowzero = true, | ||
| 1374 | .sentinel = null, | ||
| 1375 | } }); | ||
| 1376 | }, | ||
| 1377 | else => |info| @compileError("Invalid self type \"" ++ @tagName(info) ++ "\" for flexible array getter: " ++ @typeName(SelfType)), | ||
| 1378 | } | ||
| 1379 | } | ||
| 1380 | |||
| 1381 | test "Flexible Array Type" { | ||
| 1382 | const Container = extern struct { | ||
| 1383 | size: usize, | ||
| 1384 | }; | ||
| 1385 | |||
| 1386 | try testing.expectEqual(FlexibleArrayType(*Container, c_int), [*c]c_int); | ||
| 1387 | try testing.expectEqual(FlexibleArrayType(*const Container, c_int), [*c]const c_int); | ||
| 1388 | try testing.expectEqual(FlexibleArrayType(*volatile Container, c_int), [*c]volatile c_int); | ||
| 1389 | try testing.expectEqual(FlexibleArrayType(*const volatile Container, c_int), [*c]const volatile c_int); | ||
| 1390 | } |
lib/std/zig.zig+4| ... | @@ -16,6 +16,10 @@ pub const ast = @import("zig/ast.zig"); | ... | @@ -16,6 +16,10 @@ pub const ast = @import("zig/ast.zig"); |
| 16 | pub const system = @import("zig/system.zig"); | 16 | pub const system = @import("zig/system.zig"); |
| 17 | pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget; | 17 | pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget; |
| 18 | 18 | ||
| 19 | // Files needed by translate-c. | ||
| 20 | pub const c_builtins = @import("zig/c_builtins.zig"); | ||
| 21 | pub const c_translation = @import("zig/c_translation.zig"); | ||
| 22 | |||
| 19 | pub const SrcHash = [16]u8; | 23 | pub const SrcHash = [16]u8; |
| 20 | 24 | ||
| 21 | pub fn hashSrc(src: []const u8) SrcHash { | 25 | pub fn hashSrc(src: []const u8) SrcHash { |
lib/std/zig/c_builtins.zig created+196| ... | @@ -0,0 +1,196 @@ | ||
| 1 | // SPDX-License-Identifier: MIT | ||
| 2 | // Copyright (c) 2015-2021 Zig Contributors | ||
| 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. | ||
| 4 | // The MIT license requires this copyright notice to be included in all copies | ||
| 5 | // and substantial portions of the software. | ||
| 6 | |||
| 7 | const std = @import("std"); | ||
| 8 | |||
| 9 | pub inline fn __builtin_bswap16(val: u16) u16 { | ||
| 10 | return @byteSwap(u16, val); | ||
| 11 | } | ||
| 12 | pub inline fn __builtin_bswap32(val: u32) u32 { | ||
| 13 | return @byteSwap(u32, val); | ||
| 14 | } | ||
| 15 | pub inline fn __builtin_bswap64(val: u64) u64 { | ||
| 16 | return @byteSwap(u64, val); | ||
| 17 | } | ||
| 18 | |||
| 19 | pub inline fn __builtin_signbit(val: f64) c_int { | ||
| 20 | return @boolToInt(std.math.signbit(val)); | ||
| 21 | } | ||
| 22 | pub inline fn __builtin_signbitf(val: f32) c_int { | ||
| 23 | return @boolToInt(std.math.signbit(val)); | ||
| 24 | } | ||
| 25 | |||
| 26 | pub inline fn __builtin_popcount(val: c_uint) c_int { | ||
| 27 | // popcount of a c_uint will never exceed the capacity of a c_int | ||
| 28 | @setRuntimeSafety(false); | ||
| 29 | return @bitCast(c_int, @as(c_uint, @popCount(c_uint, val))); | ||
| 30 | } | ||
| 31 | pub inline fn __builtin_ctz(val: c_uint) c_int { | ||
| 32 | // Returns the number of trailing 0-bits in val, starting at the least significant bit position. | ||
| 33 | // In C if `val` is 0, the result is undefined; in zig it's the number of bits in a c_uint | ||
| 34 | @setRuntimeSafety(false); | ||
| 35 | return @bitCast(c_int, @as(c_uint, @ctz(c_uint, val))); | ||
| 36 | } | ||
| 37 | pub inline fn __builtin_clz(val: c_uint) c_int { | ||
| 38 | // Returns the number of leading 0-bits in x, starting at the most significant bit position. | ||
| 39 | // In C if `val` is 0, the result is undefined; in zig it's the number of bits in a c_uint | ||
| 40 | @setRuntimeSafety(false); | ||
| 41 | return @bitCast(c_int, @as(c_uint, @clz(c_uint, val))); | ||
| 42 | } | ||
| 43 | |||
| 44 | pub inline fn __builtin_sqrt(val: f64) f64 { | ||
| 45 | return @sqrt(val); | ||
| 46 | } | ||
| 47 | pub inline fn __builtin_sqrtf(val: f32) f32 { | ||
| 48 | return @sqrt(val); | ||
| 49 | } | ||
| 50 | |||
| 51 | pub inline fn __builtin_sin(val: f64) f64 { | ||
| 52 | return @sin(val); | ||
| 53 | } | ||
| 54 | pub inline fn __builtin_sinf(val: f32) f32 { | ||
| 55 | return @sin(val); | ||
| 56 | } | ||
| 57 | pub inline fn __builtin_cos(val: f64) f64 { | ||
| 58 | return @cos(val); | ||
| 59 | } | ||
| 60 | pub inline fn __builtin_cosf(val: f32) f32 { | ||
| 61 | return @cos(val); | ||
| 62 | } | ||
| 63 | |||
| 64 | pub inline fn __builtin_exp(val: f64) f64 { | ||
| 65 | return @exp(val); | ||
| 66 | } | ||
| 67 | pub inline fn __builtin_expf(val: f32) f32 { | ||
| 68 | return @exp(val); | ||
| 69 | } | ||
| 70 | pub inline fn __builtin_exp2(val: f64) f64 { | ||
| 71 | return @exp2(val); | ||
| 72 | } | ||
| 73 | pub inline fn __builtin_exp2f(val: f32) f32 { | ||
| 74 | return @exp2(val); | ||
| 75 | } | ||
| 76 | pub inline fn __builtin_log(val: f64) f64 { | ||
| 77 | return @log(val); | ||
| 78 | } | ||
| 79 | pub inline fn __builtin_logf(val: f32) f32 { | ||
| 80 | return @log(val); | ||
| 81 | } | ||
| 82 | pub inline fn __builtin_log2(val: f64) f64 { | ||
| 83 | return @log2(val); | ||
| 84 | } | ||
| 85 | pub inline fn __builtin_log2f(val: f32) f32 { | ||
| 86 | return @log2(val); | ||
| 87 | } | ||
| 88 | pub inline fn __builtin_log10(val: f64) f64 { | ||
| 89 | return @log10(val); | ||
| 90 | } | ||
| 91 | pub inline fn __builtin_log10f(val: f32) f32 { | ||
| 92 | return @log10(val); | ||
| 93 | } | ||
| 94 | |||
| 95 | // Standard C Library bug: The absolute value of the most negative integer remains negative. | ||
| 96 | pub inline fn __builtin_abs(val: c_int) c_int { | ||
| 97 | return std.math.absInt(val) catch std.math.minInt(c_int); | ||
| 98 | } | ||
| 99 | pub inline fn __builtin_fabs(val: f64) f64 { | ||
| 100 | return @fabs(val); | ||
| 101 | } | ||
| 102 | pub inline fn __builtin_fabsf(val: f32) f32 { | ||
| 103 | return @fabs(val); | ||
| 104 | } | ||
| 105 | |||
| 106 | pub inline fn __builtin_floor(val: f64) f64 { | ||
| 107 | return @floor(val); | ||
| 108 | } | ||
| 109 | pub inline fn __builtin_floorf(val: f32) f32 { | ||
| 110 | return @floor(val); | ||
| 111 | } | ||
| 112 | pub inline fn __builtin_ceil(val: f64) f64 { | ||
| 113 | return @ceil(val); | ||
| 114 | } | ||
| 115 | pub inline fn __builtin_ceilf(val: f32) f32 { | ||
| 116 | return @ceil(val); | ||
| 117 | } | ||
| 118 | pub inline fn __builtin_trunc(val: f64) f64 { | ||
| 119 | return @trunc(val); | ||
| 120 | } | ||
| 121 | pub inline fn __builtin_truncf(val: f32) f32 { | ||
| 122 | return @trunc(val); | ||
| 123 | } | ||
| 124 | pub inline fn __builtin_round(val: f64) f64 { | ||
| 125 | return @round(val); | ||
| 126 | } | ||
| 127 | pub inline fn __builtin_roundf(val: f32) f32 { | ||
| 128 | return @round(val); | ||
| 129 | } | ||
| 130 | |||
| 131 | pub inline fn __builtin_strlen(s: [*c]const u8) usize { | ||
| 132 | return std.mem.lenZ(s); | ||
| 133 | } | ||
| 134 | pub inline fn __builtin_strcmp(s1: [*c]const u8, s2: [*c]const u8) c_int { | ||
| 135 | return @as(c_int, std.cstr.cmp(s1, s2)); | ||
| 136 | } | ||
| 137 | |||
| 138 | pub inline fn __builtin_object_size(ptr: ?*const c_void, ty: c_int) usize { | ||
| 139 | // clang semantics match gcc's: https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html | ||
| 140 | // If it is not possible to determine which objects ptr points to at compile time, | ||
| 141 | // __builtin_object_size should return (size_t) -1 for type 0 or 1 and (size_t) 0 | ||
| 142 | // for type 2 or 3. | ||
| 143 | if (ty == 0 or ty == 1) return @bitCast(usize, -@as(isize, 1)); | ||
| 144 | if (ty == 2 or ty == 3) return 0; | ||
| 145 | unreachable; | ||
| 146 | } | ||
| 147 | |||
| 148 | pub inline fn __builtin___memset_chk( | ||
| 149 | dst: ?*c_void, | ||
| 150 | val: c_int, | ||
| 151 | len: usize, | ||
| 152 | remaining: usize, | ||
| 153 | ) ?*c_void { | ||
| 154 | if (len > remaining) @panic("std.c.builtins.memset_chk called with len > remaining"); | ||
| 155 | return __builtin_memset(dst, val, len); | ||
| 156 | } | ||
| 157 | |||
| 158 | pub inline fn __builtin_memset(dst: ?*c_void, val: c_int, len: usize) ?*c_void { | ||
| 159 | const dst_cast = @ptrCast([*c]u8, dst); | ||
| 160 | @memset(dst_cast, @bitCast(u8, @truncate(i8, val)), len); | ||
| 161 | return dst; | ||
| 162 | } | ||
| 163 | |||
| 164 | pub inline fn __builtin___memcpy_chk( | ||
| 165 | noalias dst: ?*c_void, | ||
| 166 | noalias src: ?*const c_void, | ||
| 167 | len: usize, | ||
| 168 | remaining: usize, | ||
| 169 | ) ?*c_void { | ||
| 170 | if (len > remaining) @panic("std.c.builtins.memcpy_chk called with len > remaining"); | ||
| 171 | return __builtin_memcpy(dst, src, len); | ||
| 172 | } | ||
| 173 | |||
| 174 | pub inline fn __builtin_memcpy( | ||
| 175 | noalias dst: ?*c_void, | ||
| 176 | noalias src: ?*const c_void, | ||
| 177 | len: usize, | ||
| 178 | ) ?*c_void { | ||
| 179 | const dst_cast = @ptrCast([*c]u8, dst); | ||
| 180 | const src_cast = @ptrCast([*c]const u8, src); | ||
| 181 | |||
| 182 | @memcpy(dst_cast, src_cast, len); | ||
| 183 | return dst; | ||
| 184 | } | ||
| 185 | |||
| 186 | /// The return value of __builtin_expect is `expr`. `c` is the expected value | ||
| 187 | /// of `expr` and is used as a hint to the compiler in C. Here it is unused. | ||
| 188 | pub inline fn __builtin_expect(expr: c_long, c: c_long) c_long { | ||
| 189 | return expr; | ||
| 190 | } | ||
| 191 | |||
| 192 | // __builtin_alloca_with_align is not currently implemented. | ||
| 193 | // It is used in a run-translated-c test and a test-translate-c test to ensure that non-implemented | ||
| 194 | // builtins are correctly demoted. If you implement __builtin_alloca_with_align, please update the | ||
| 195 | // run-translated-c test and the test-translate-c test to use a different non-implemented builtin. | ||
| 196 | // pub fn __builtin_alloca_with_align(size: usize, alignment: usize) callconv(.Inline) *c_void {} | ||
lib/std/zig/c_translation.zig created+385| ... | @@ -0,0 +1,385 @@ | ||
| 1 | // SPDX-License-Identifier: MIT | ||
| 2 | // Copyright (c) 2015-2021 Zig Contributors | ||
| 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. | ||
| 4 | // The MIT license requires this copyright notice to be included in all copies | ||
| 5 | // and substantial portions of the software. | ||
| 6 | |||
| 7 | const std = @import("std"); | ||
| 8 | const testing = std.testing; | ||
| 9 | const math = std.math; | ||
| 10 | const mem = std.mem; | ||
| 11 | |||
| 12 | /// Given a type and value, cast the value to the type as c would. | ||
| 13 | pub fn cast(comptime DestType: type, target: anytype) DestType { | ||
| 14 | // this function should behave like transCCast in translate-c, except it's for macros and enums | ||
| 15 | const SourceType = @TypeOf(target); | ||
| 16 | switch (@typeInfo(DestType)) { | ||
| 17 | .Fn, .Pointer => return castToPtr(DestType, SourceType, target), | ||
| 18 | .Optional => |dest_opt| { | ||
| 19 | if (@typeInfo(dest_opt.child) == .Pointer or @typeInfo(dest_opt.child) == .Fn) { | ||
| 20 | return castToPtr(DestType, SourceType, target); | ||
| 21 | } | ||
| 22 | }, | ||
| 23 | .Enum => |enum_type| { | ||
| 24 | if (@typeInfo(SourceType) == .Int or @typeInfo(SourceType) == .ComptimeInt) { | ||
| 25 | const intermediate = cast(enum_type.tag_type, target); | ||
| 26 | return @intToEnum(DestType, intermediate); | ||
| 27 | } | ||
| 28 | }, | ||
| 29 | .Int => { | ||
| 30 | switch (@typeInfo(SourceType)) { | ||
| 31 | .Pointer => { | ||
| 32 | return castInt(DestType, @ptrToInt(target)); | ||
| 33 | }, | ||
| 34 | .Optional => |opt| { | ||
| 35 | if (@typeInfo(opt.child) == .Pointer) { | ||
| 36 | return castInt(DestType, @ptrToInt(target)); | ||
| 37 | } | ||
| 38 | }, | ||
| 39 | .Enum => { | ||
| 40 | return castInt(DestType, @enumToInt(target)); | ||
| 41 | }, | ||
| 42 | .Int => { | ||
| 43 | return castInt(DestType, target); | ||
| 44 | }, | ||
| 45 | else => {}, | ||
| 46 | } | ||
| 47 | }, | ||
| 48 | else => {}, | ||
| 49 | } | ||
| 50 | return @as(DestType, target); | ||
| 51 | } | ||
| 52 | |||
| 53 | fn castInt(comptime DestType: type, target: anytype) DestType { | ||
| 54 | const dest = @typeInfo(DestType).Int; | ||
| 55 | const source = @typeInfo(@TypeOf(target)).Int; | ||
| 56 | |||
| 57 | if (dest.bits < source.bits) | ||
| 58 | return @bitCast(DestType, @truncate(std.meta.Int(source.signedness, dest.bits), target)) | ||
| 59 | else | ||
| 60 | return @bitCast(DestType, @as(std.meta.Int(source.signedness, dest.bits), target)); | ||
| 61 | } | ||
| 62 | |||
| 63 | fn castPtr(comptime DestType: type, target: anytype) DestType { | ||
| 64 | const dest = ptrInfo(DestType); | ||
| 65 | const source = ptrInfo(@TypeOf(target)); | ||
| 66 | |||
| 67 | if (source.is_const and !dest.is_const or source.is_volatile and !dest.is_volatile) | ||
| 68 | return @intToPtr(DestType, @ptrToInt(target)) | ||
| 69 | else if (@typeInfo(dest.child) == .Opaque) | ||
| 70 | // dest.alignment would error out | ||
| 71 | return @ptrCast(DestType, target) | ||
| 72 | else | ||
| 73 | return @ptrCast(DestType, @alignCast(dest.alignment, target)); | ||
| 74 | } | ||
| 75 | |||
| 76 | fn castToPtr(comptime DestType: type, comptime SourceType: type, target: anytype) DestType { | ||
| 77 | switch (@typeInfo(SourceType)) { | ||
| 78 | .Int => { | ||
| 79 | return @intToPtr(DestType, castInt(usize, target)); | ||
| 80 | }, | ||
| 81 | .ComptimeInt => { | ||
| 82 | if (target < 0) | ||
| 83 | return @intToPtr(DestType, @bitCast(usize, @intCast(isize, target))) | ||
| 84 | else | ||
| 85 | return @intToPtr(DestType, @intCast(usize, target)); | ||
| 86 | }, | ||
| 87 | .Pointer => { | ||
| 88 | return castPtr(DestType, target); | ||
| 89 | }, | ||
| 90 | .Optional => |target_opt| { | ||
| 91 | if (@typeInfo(target_opt.child) == .Pointer) { | ||
| 92 | return castPtr(DestType, target); | ||
| 93 | } | ||
| 94 | }, | ||
| 95 | else => {}, | ||
| 96 | } | ||
| 97 | return @as(DestType, target); | ||
| 98 | } | ||
| 99 | |||
| 100 | fn ptrInfo(comptime PtrType: type) std.builtin.TypeInfo.Pointer { | ||
| 101 | return switch (@typeInfo(PtrType)) { | ||
| 102 | .Optional => |opt_info| @typeInfo(opt_info.child).Pointer, | ||
| 103 | .Pointer => |ptr_info| ptr_info, | ||
| 104 | else => unreachable, | ||
| 105 | }; | ||
| 106 | } | ||
| 107 | |||
| 108 | test "cast" { | ||
| 109 | const E = enum(u2) { | ||
| 110 | Zero, | ||
| 111 | One, | ||
| 112 | Two, | ||
| 113 | }; | ||
| 114 | |||
| 115 | var i = @as(i64, 10); | ||
| 116 | |||
| 117 | try testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16)); | ||
| 118 | try testing.expect(cast(*u64, &i).* == @as(u64, 10)); | ||
| 119 | try testing.expect(cast(*i64, @as(?*align(1) i64, &i)) == &i); | ||
| 120 | |||
| 121 | try testing.expect(cast(?*u8, 2) == @intToPtr(*u8, 2)); | ||
| 122 | try testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i); | ||
| 123 | try testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i); | ||
| 124 | |||
| 125 | try testing.expect(cast(E, 1) == .One); | ||
| 126 | |||
| 127 | try testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4))); | ||
| 128 | try testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4))); | ||
| 129 | try testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10))); | ||
| 130 | try testing.expectEqual(@as(u8, 2), cast(u8, E.Two)); | ||
| 131 | |||
| 132 | try testing.expectEqual(@bitCast(i32, @as(u32, 0x8000_0000)), cast(i32, @as(u32, 0x8000_0000))); | ||
| 133 | |||
| 134 | try testing.expectEqual(@intToPtr(*u8, 2), cast(*u8, @intToPtr(*const u8, 2))); | ||
| 135 | try testing.expectEqual(@intToPtr(*u8, 2), cast(*u8, @intToPtr(*volatile u8, 2))); | ||
| 136 | |||
| 137 | try testing.expectEqual(@intToPtr(?*c_void, 2), cast(?*c_void, @intToPtr(*u8, 2))); | ||
| 138 | |||
| 139 | const C_ENUM = enum(c_int) { | ||
| 140 | A = 0, | ||
| 141 | B, | ||
| 142 | C, | ||
| 143 | _, | ||
| 144 | }; | ||
| 145 | try testing.expectEqual(cast(C_ENUM, @as(i64, -1)), @intToEnum(C_ENUM, -1)); | ||
| 146 | try testing.expectEqual(cast(C_ENUM, @as(i8, 1)), .B); | ||
| 147 | try testing.expectEqual(cast(C_ENUM, @as(u64, 1)), .B); | ||
| 148 | try testing.expectEqual(cast(C_ENUM, @as(u64, 42)), @intToEnum(C_ENUM, 42)); | ||
| 149 | |||
| 150 | var foo: c_int = -1; | ||
| 151 | try testing.expect(cast(*c_void, -1) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)))); | ||
| 152 | try testing.expect(cast(*c_void, foo) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)))); | ||
| 153 | try testing.expect(cast(?*c_void, -1) == @intToPtr(?*c_void, @bitCast(usize, @as(isize, -1)))); | ||
| 154 | try testing.expect(cast(?*c_void, foo) == @intToPtr(?*c_void, @bitCast(usize, @as(isize, -1)))); | ||
| 155 | |||
| 156 | const FnPtr = ?fn (*c_void) void; | ||
| 157 | try testing.expect(cast(FnPtr, 0) == @intToPtr(FnPtr, @as(usize, 0))); | ||
| 158 | try testing.expect(cast(FnPtr, foo) == @intToPtr(FnPtr, @bitCast(usize, @as(isize, -1)))); | ||
| 159 | } | ||
| 160 | |||
| 161 | /// Given a value returns its size as C's sizeof operator would. | ||
| 162 | pub fn sizeof(target: anytype) usize { | ||
| 163 | const T: type = if (@TypeOf(target) == type) target else @TypeOf(target); | ||
| 164 | switch (@typeInfo(T)) { | ||
| 165 | .Float, .Int, .Struct, .Union, .Enum, .Array, .Bool, .Vector => return @sizeOf(T), | ||
| 166 | .Fn => { | ||
| 167 | // sizeof(main) returns 1, sizeof(&main) returns pointer size. | ||
| 168 | // We cannot distinguish those types in Zig, so use pointer size. | ||
| 169 | return @sizeOf(T); | ||
| 170 | }, | ||
| 171 | .Null => return @sizeOf(*c_void), | ||
| 172 | .Void => { | ||
| 173 | // Note: sizeof(void) is 1 on clang/gcc and 0 on MSVC. | ||
| 174 | return 1; | ||
| 175 | }, | ||
| 176 | .Opaque => { | ||
| 177 | if (T == c_void) { | ||
| 178 | // Note: sizeof(void) is 1 on clang/gcc and 0 on MSVC. | ||
| 179 | return 1; | ||
| 180 | } else { | ||
| 181 | @compileError("Cannot use C sizeof on opaque type " ++ @typeName(T)); | ||
| 182 | } | ||
| 183 | }, | ||
| 184 | .Optional => |opt| { | ||
| 185 | if (@typeInfo(opt.child) == .Pointer) { | ||
| 186 | return sizeof(opt.child); | ||
| 187 | } else { | ||
| 188 | @compileError("Cannot use C sizeof on non-pointer optional " ++ @typeName(T)); | ||
| 189 | } | ||
| 190 | }, | ||
| 191 | .Pointer => |ptr| { | ||
| 192 | if (ptr.size == .Slice) { | ||
| 193 | @compileError("Cannot use C sizeof on slice type " ++ @typeName(T)); | ||
| 194 | } | ||
| 195 | // for strings, sizeof("a") returns 2. | ||
| 196 | // normal pointer decay scenarios from C are handled | ||
| 197 | // in the .Array case above, but strings remain literals | ||
| 198 | // and are therefore always pointers, so they need to be | ||
| 199 | // specially handled here. | ||
| 200 | if (ptr.size == .One and ptr.is_const and @typeInfo(ptr.child) == .Array) { | ||
| 201 | const array_info = @typeInfo(ptr.child).Array; | ||
| 202 | if ((array_info.child == u8 or array_info.child == u16) and | ||
| 203 | array_info.sentinel != null and | ||
| 204 | array_info.sentinel.? == 0) | ||
| 205 | { | ||
| 206 | // length of the string plus one for the null terminator. | ||
| 207 | return (array_info.len + 1) * @sizeOf(array_info.child); | ||
| 208 | } | ||
| 209 | } | ||
| 210 | // When zero sized pointers are removed, this case will no | ||
| 211 | // longer be reachable and can be deleted. | ||
| 212 | if (@sizeOf(T) == 0) { | ||
| 213 | return @sizeOf(*c_void); | ||
| 214 | } | ||
| 215 | return @sizeOf(T); | ||
| 216 | }, | ||
| 217 | .ComptimeFloat => return @sizeOf(f64), // TODO c_double #3999 | ||
| 218 | .ComptimeInt => { | ||
| 219 | // TODO to get the correct result we have to translate | ||
| 220 | // `1073741824 * 4` as `int(1073741824) *% int(4)` since | ||
| 221 | // sizeof(1073741824 * 4) != sizeof(4294967296). | ||
| 222 | |||
| 223 | // TODO test if target fits in int, long or long long | ||
| 224 | return @sizeOf(c_int); | ||
| 225 | }, | ||
| 226 | else => @compileError("std.meta.sizeof does not support type " ++ @typeName(T)), | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | test "sizeof" { | ||
| 231 | const E = enum(c_int) { One, _ }; | ||
| 232 | const S = extern struct { a: u32 }; | ||
| 233 | |||
| 234 | const ptr_size = @sizeOf(*c_void); | ||
| 235 | |||
| 236 | try testing.expect(sizeof(u32) == 4); | ||
| 237 | try testing.expect(sizeof(@as(u32, 2)) == 4); | ||
| 238 | try testing.expect(sizeof(2) == @sizeOf(c_int)); | ||
| 239 | |||
| 240 | try testing.expect(sizeof(2.0) == @sizeOf(f64)); | ||
| 241 | |||
| 242 | try testing.expect(sizeof(E) == @sizeOf(c_int)); | ||
| 243 | try testing.expect(sizeof(E.One) == @sizeOf(c_int)); | ||
| 244 | |||
| 245 | try testing.expect(sizeof(S) == 4); | ||
| 246 | |||
| 247 | try testing.expect(sizeof([_]u32{ 4, 5, 6 }) == 12); | ||
| 248 | try testing.expect(sizeof([3]u32) == 12); | ||
| 249 | try testing.expect(sizeof([3:0]u32) == 16); | ||
| 250 | try testing.expect(sizeof(&[_]u32{ 4, 5, 6 }) == ptr_size); | ||
| 251 | |||
| 252 | try testing.expect(sizeof(*u32) == ptr_size); | ||
| 253 | try testing.expect(sizeof([*]u32) == ptr_size); | ||
| 254 | try testing.expect(sizeof([*c]u32) == ptr_size); | ||
| 255 | try testing.expect(sizeof(?*u32) == ptr_size); | ||
| 256 | try testing.expect(sizeof(?[*]u32) == ptr_size); | ||
| 257 | try testing.expect(sizeof(*c_void) == ptr_size); | ||
| 258 | try testing.expect(sizeof(*void) == ptr_size); | ||
| 259 | try testing.expect(sizeof(null) == ptr_size); | ||
| 260 | |||
| 261 | try testing.expect(sizeof("foobar") == 7); | ||
| 262 | try testing.expect(sizeof(&[_:0]u16{ 'f', 'o', 'o', 'b', 'a', 'r' }) == 14); | ||
| 263 | try testing.expect(sizeof(*const [4:0]u8) == 5); | ||
| 264 | try testing.expect(sizeof(*[4:0]u8) == ptr_size); | ||
| 265 | try testing.expect(sizeof([*]const [4:0]u8) == ptr_size); | ||
| 266 | try testing.expect(sizeof(*const *const [4:0]u8) == ptr_size); | ||
| 267 | try testing.expect(sizeof(*const [4]u8) == ptr_size); | ||
| 268 | |||
| 269 | try testing.expect(sizeof(sizeof) == @sizeOf(@TypeOf(sizeof))); | ||
| 270 | |||
| 271 | try testing.expect(sizeof(void) == 1); | ||
| 272 | try testing.expect(sizeof(c_void) == 1); | ||
| 273 | } | ||
| 274 | |||
| 275 | pub const CIntLiteralRadix = enum { decimal, octal, hexadecimal }; | ||
| 276 | |||
| 277 | fn PromoteIntLiteralReturnType(comptime SuffixType: type, comptime number: comptime_int, comptime radix: CIntLiteralRadix) type { | ||
| 278 | const signed_decimal = [_]type{ c_int, c_long, c_longlong }; | ||
| 279 | const signed_oct_hex = [_]type{ c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong }; | ||
| 280 | const unsigned = [_]type{ c_uint, c_ulong, c_ulonglong }; | ||
| 281 | |||
| 282 | const list: []const type = if (@typeInfo(SuffixType).Int.signedness == .unsigned) | ||
| 283 | &unsigned | ||
| 284 | else if (radix == .decimal) | ||
| 285 | &signed_decimal | ||
| 286 | else | ||
| 287 | &signed_oct_hex; | ||
| 288 | |||
| 289 | var pos = mem.indexOfScalar(type, list, SuffixType).?; | ||
| 290 | |||
| 291 | while (pos < list.len) : (pos += 1) { | ||
| 292 | if (number >= math.minInt(list[pos]) and number <= math.maxInt(list[pos])) { | ||
| 293 | return list[pos]; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | @compileError("Integer literal is too large"); | ||
| 297 | } | ||
| 298 | |||
| 299 | /// Promote the type of an integer literal until it fits as C would. | ||
| 300 | pub fn promoteIntLiteral( | ||
| 301 | comptime SuffixType: type, | ||
| 302 | comptime number: comptime_int, | ||
| 303 | comptime radix: CIntLiteralRadix, | ||
| 304 | ) PromoteIntLiteralReturnType(SuffixType, number, radix) { | ||
| 305 | return number; | ||
| 306 | } | ||
| 307 | |||
| 308 | test "promoteIntLiteral" { | ||
| 309 | const signed_hex = promoteIntLiteral(c_int, math.maxInt(c_int) + 1, .hexadecimal); | ||
| 310 | try testing.expectEqual(c_uint, @TypeOf(signed_hex)); | ||
| 311 | |||
| 312 | if (math.maxInt(c_longlong) == math.maxInt(c_int)) return; | ||
| 313 | |||
| 314 | const signed_decimal = promoteIntLiteral(c_int, math.maxInt(c_int) + 1, .decimal); | ||
| 315 | const unsigned = promoteIntLiteral(c_uint, math.maxInt(c_uint) + 1, .hexadecimal); | ||
| 316 | |||
| 317 | if (math.maxInt(c_long) > math.maxInt(c_int)) { | ||
| 318 | try testing.expectEqual(c_long, @TypeOf(signed_decimal)); | ||
| 319 | try testing.expectEqual(c_ulong, @TypeOf(unsigned)); | ||
| 320 | } else { | ||
| 321 | try testing.expectEqual(c_longlong, @TypeOf(signed_decimal)); | ||
| 322 | try testing.expectEqual(c_ulonglong, @TypeOf(unsigned)); | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | /// Convert from clang __builtin_shufflevector index to Zig @shuffle index | ||
| 327 | /// clang requires __builtin_shufflevector index arguments to be integer constants. | ||
| 328 | /// negative values for `this_index` indicate "don't care" so we arbitrarily choose 0 | ||
| 329 | /// clang enforces that `this_index` is less than the total number of vector elements | ||
| 330 | /// See https://ziglang.org/documentation/master/#shuffle | ||
| 331 | /// See https://clang.llvm.org/docs/LanguageExtensions.html#langext-builtin-shufflevector | ||
| 332 | pub fn shuffleVectorIndex(comptime this_index: c_int, comptime source_vector_len: usize) i32 { | ||
| 333 | if (this_index <= 0) return 0; | ||
| 334 | |||
| 335 | const positive_index = @intCast(usize, this_index); | ||
| 336 | if (positive_index < source_vector_len) return @intCast(i32, this_index); | ||
| 337 | const b_index = positive_index - source_vector_len; | ||
| 338 | return ~@intCast(i32, b_index); | ||
| 339 | } | ||
| 340 | |||
| 341 | test "shuffleVectorIndex" { | ||
| 342 | const vector_len: usize = 4; | ||
| 343 | |||
| 344 | try testing.expect(shuffleVectorIndex(-1, vector_len) == 0); | ||
| 345 | |||
| 346 | try testing.expect(shuffleVectorIndex(0, vector_len) == 0); | ||
| 347 | try testing.expect(shuffleVectorIndex(1, vector_len) == 1); | ||
| 348 | try testing.expect(shuffleVectorIndex(2, vector_len) == 2); | ||
| 349 | try testing.expect(shuffleVectorIndex(3, vector_len) == 3); | ||
| 350 | |||
| 351 | try testing.expect(shuffleVectorIndex(4, vector_len) == -1); | ||
| 352 | try testing.expect(shuffleVectorIndex(5, vector_len) == -2); | ||
| 353 | try testing.expect(shuffleVectorIndex(6, vector_len) == -3); | ||
| 354 | try testing.expect(shuffleVectorIndex(7, vector_len) == -4); | ||
| 355 | } | ||
| 356 | |||
| 357 | /// Constructs a [*c] pointer with the const and volatile annotations | ||
| 358 | /// from SelfType for pointing to a C flexible array of ElementType. | ||
| 359 | pub fn FlexibleArrayType(comptime SelfType: type, ElementType: type) type { | ||
| 360 | switch (@typeInfo(SelfType)) { | ||
| 361 | .Pointer => |ptr| { | ||
| 362 | return @Type(.{ .Pointer = .{ | ||
| 363 | .size = .C, | ||
| 364 | .is_const = ptr.is_const, | ||
| 365 | .is_volatile = ptr.is_volatile, | ||
| 366 | .alignment = @alignOf(ElementType), | ||
| 367 | .child = ElementType, | ||
| 368 | .is_allowzero = true, | ||
| 369 | .sentinel = null, | ||
| 370 | } }); | ||
| 371 | }, | ||
| 372 | else => |info| @compileError("Invalid self type \"" ++ @tagName(info) ++ "\" for flexible array getter: " ++ @typeName(SelfType)), | ||
| 373 | } | ||
| 374 | } | ||
| 375 | |||
| 376 | test "Flexible Array Type" { | ||
| 377 | const Container = extern struct { | ||
| 378 | size: usize, | ||
| 379 | }; | ||
| 380 | |||
| 381 | try testing.expectEqual(FlexibleArrayType(*Container, c_int), [*c]c_int); | ||
| 382 | try testing.expectEqual(FlexibleArrayType(*const Container, c_int), [*c]const c_int); | ||
| 383 | try testing.expectEqual(FlexibleArrayType(*volatile Container, c_int), [*c]volatile c_int); | ||
| 384 | try testing.expectEqual(FlexibleArrayType(*const volatile Container, c_int), [*c]const volatile c_int); | ||
| 385 | } | ||
src/translate_c.zig+35-23| ... | @@ -12,7 +12,6 @@ const meta = std.meta; | ... | @@ -12,7 +12,6 @@ const meta = std.meta; |
| 12 | const ast = @import("translate_c/ast.zig"); | 12 | const ast = @import("translate_c/ast.zig"); |
| 13 | const Node = ast.Node; | 13 | const Node = ast.Node; |
| 14 | const Tag = Node.Tag; | 14 | const Tag = Node.Tag; |
| 15 | const c_builtins = std.c.builtins; | ||
| 16 | 15 | ||
| 17 | const CallingConvention = std.builtin.CallingConvention; | 16 | const CallingConvention = std.builtin.CallingConvention; |
| 18 | 17 | ||
| ... | @@ -863,7 +862,7 @@ fn buildFlexibleArrayFn( | ... | @@ -863,7 +862,7 @@ fn buildFlexibleArrayFn( |
| 863 | defer block_scope.deinit(); | 862 | defer block_scope.deinit(); |
| 864 | 863 | ||
| 865 | const intermediate_type_name = try block_scope.makeMangledName(c, "Intermediate"); | 864 | const intermediate_type_name = try block_scope.makeMangledName(c, "Intermediate"); |
| 866 | const intermediate_type = try Tag.std_meta_flexible_array_type.create(c.arena, .{ .lhs = self_type, .rhs = u8_type }); | 865 | const intermediate_type = try Tag.helpers_flexible_array_type.create(c.arena, .{ .lhs = self_type, .rhs = u8_type }); |
| 867 | const intermediate_type_decl = try Tag.var_simple.create(c.arena, .{ | 866 | const intermediate_type_decl = try Tag.var_simple.create(c.arena, .{ |
| 868 | .name = intermediate_type_name, | 867 | .name = intermediate_type_name, |
| 869 | .init = intermediate_type, | 868 | .init = intermediate_type, |
| ... | @@ -872,7 +871,7 @@ fn buildFlexibleArrayFn( | ... | @@ -872,7 +871,7 @@ fn buildFlexibleArrayFn( |
| 872 | const intermediate_type_ident = try Tag.identifier.create(c.arena, intermediate_type_name); | 871 | const intermediate_type_ident = try Tag.identifier.create(c.arena, intermediate_type_name); |
| 873 | 872 | ||
| 874 | const return_type_name = try block_scope.makeMangledName(c, "ReturnType"); | 873 | const return_type_name = try block_scope.makeMangledName(c, "ReturnType"); |
| 875 | const return_type = try Tag.std_meta_flexible_array_type.create(c.arena, .{ .lhs = self_type, .rhs = element_type }); | 874 | const return_type = try Tag.helpers_flexible_array_type.create(c.arena, .{ .lhs = self_type, .rhs = element_type }); |
| 876 | const return_type_decl = try Tag.var_simple.create(c.arena, .{ | 875 | const return_type_decl = try Tag.var_simple.create(c.arena, .{ |
| 877 | .name = return_type_name, | 876 | .name = return_type_name, |
| 878 | .init = return_type, | 877 | .init = return_type, |
| ... | @@ -1290,9 +1289,19 @@ fn transStmt( | ... | @@ -1290,9 +1289,19 @@ fn transStmt( |
| 1290 | return maybeSuppressResult(c, scope, result_used, shuffle_vec_node); | 1289 | return maybeSuppressResult(c, scope, result_used, shuffle_vec_node); |
| 1291 | }, | 1290 | }, |
| 1292 | // When adding new cases here, see comment for maybeBlockify() | 1291 | // When adding new cases here, see comment for maybeBlockify() |
| 1293 | else => { | 1292 | .GCCAsmStmtClass, |
| 1294 | return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)}); | 1293 | .GotoStmtClass, |
| 1295 | }, | 1294 | .IndirectGotoStmtClass, |
| 1295 | .AttributedStmtClass, | ||
| 1296 | .AddrLabelExprClass, | ||
| 1297 | .AtomicExprClass, | ||
| 1298 | .BlockExprClass, | ||
| 1299 | .UserDefinedLiteralClass, | ||
| 1300 | .BuiltinBitCastExprClass, | ||
| 1301 | .DesignatedInitExprClass, | ||
| 1302 | .LabelStmtClass, | ||
| 1303 | => return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)}), | ||
| 1304 | else => return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "unsupported stmt class {s}", .{@tagName(sc)}), | ||
| 1296 | } | 1305 | } |
| 1297 | } | 1306 | } |
| 1298 | 1307 | ||
| ... | @@ -1374,7 +1383,7 @@ fn makeShuffleMask(c: *Context, scope: *Scope, expr: *const clang.ShuffleVectorE | ... | @@ -1374,7 +1383,7 @@ fn makeShuffleMask(c: *Context, scope: *Scope, expr: *const clang.ShuffleVectorE |
| 1374 | 1383 | ||
| 1375 | for (init_list) |*init, i| { | 1384 | for (init_list) |*init, i| { |
| 1376 | const index_expr = try transExprCoercing(c, scope, expr.getExpr(@intCast(c_uint, i + 2)), .used); | 1385 | const index_expr = try transExprCoercing(c, scope, expr.getExpr(@intCast(c_uint, i + 2)), .used); |
| 1377 | const converted_index = try Tag.std_meta_shuffle_vector_index.create(c.arena, .{ .lhs = index_expr, .rhs = vector_len }); | 1386 | const converted_index = try Tag.helpers_shuffle_vector_index.create(c.arena, .{ .lhs = index_expr, .rhs = vector_len }); |
| 1378 | init.* = converted_index; | 1387 | init.* = converted_index; |
| 1379 | } | 1388 | } |
| 1380 | 1389 | ||
| ... | @@ -1820,13 +1829,10 @@ fn transDeclStmtOne( | ... | @@ -1820,13 +1829,10 @@ fn transDeclStmtOne( |
| 1820 | .Function => { | 1829 | .Function => { |
| 1821 | try visitFnDecl(c, @ptrCast(*const clang.FunctionDecl, decl)); | 1830 | try visitFnDecl(c, @ptrCast(*const clang.FunctionDecl, decl)); |
| 1822 | }, | 1831 | }, |
| 1823 | else => |kind| return fail( | 1832 | else => { |
| 1824 | c, | 1833 | const decl_name = try c.str(decl.getDeclKindName()); |
| 1825 | error.UnsupportedTranslation, | 1834 | try warn(c, &c.global_scope.base, decl.getLocation(), "ignoring {s} declaration", .{decl_name}); |
| 1826 | decl.getLocation(), | 1835 | }, |
| 1827 | "TODO implement translation of DeclStmt kind {s}", | ||
| 1828 | .{@tagName(kind)}, | ||
| 1829 | ), | ||
| 1830 | } | 1836 | } |
| 1831 | } | 1837 | } |
| 1832 | 1838 | ||
| ... | @@ -1902,7 +1908,7 @@ fn transImplicitCastExpr( | ... | @@ -1902,7 +1908,7 @@ fn transImplicitCastExpr( |
| 1902 | const ne = try Tag.not_equal.create(c.arena, .{ .lhs = ptr_to_int, .rhs = Tag.zero_literal.init() }); | 1908 | const ne = try Tag.not_equal.create(c.arena, .{ .lhs = ptr_to_int, .rhs = Tag.zero_literal.init() }); |
| 1903 | return maybeSuppressResult(c, scope, result_used, ne); | 1909 | return maybeSuppressResult(c, scope, result_used, ne); |
| 1904 | }, | 1910 | }, |
| 1905 | .IntegralToBoolean => { | 1911 | .IntegralToBoolean, .FloatingToBoolean => { |
| 1906 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used); | 1912 | const sub_expr_node = try transExpr(c, scope, sub_expr, .used); |
| 1907 | 1913 | ||
| 1908 | // The expression is already a boolean one, return it as-is | 1914 | // The expression is already a boolean one, return it as-is |
| ... | @@ -1924,14 +1930,14 @@ fn transImplicitCastExpr( | ... | @@ -1924,14 +1930,14 @@ fn transImplicitCastExpr( |
| 1924 | c, | 1930 | c, |
| 1925 | error.UnsupportedTranslation, | 1931 | error.UnsupportedTranslation, |
| 1926 | @ptrCast(*const clang.Stmt, expr).getBeginLoc(), | 1932 | @ptrCast(*const clang.Stmt, expr).getBeginLoc(), |
| 1927 | "TODO implement translation of CastKind {s}", | 1933 | "unsupported CastKind {s}", |
| 1928 | .{@tagName(kind)}, | 1934 | .{@tagName(kind)}, |
| 1929 | ), | 1935 | ), |
| 1930 | } | 1936 | } |
| 1931 | } | 1937 | } |
| 1932 | 1938 | ||
| 1933 | fn isBuiltinDefined(name: []const u8) bool { | 1939 | fn isBuiltinDefined(name: []const u8) bool { |
| 1934 | inline for (meta.declarations(c_builtins)) |decl| { | 1940 | inline for (meta.declarations(std.zig.c_builtins)) |decl| { |
| 1935 | if (std.mem.eql(u8, name, decl.name)) return true; | 1941 | if (std.mem.eql(u8, name, decl.name)) return true; |
| 1936 | } | 1942 | } |
| 1937 | return false; | 1943 | return false; |
| ... | @@ -2358,8 +2364,10 @@ fn transCCast( | ... | @@ -2358,8 +2364,10 @@ fn transCCast( |
| 2358 | return Tag.float_to_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 2364 | return Tag.float_to_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); |
| 2359 | } | 2365 | } |
| 2360 | if (!cIsFloating(src_type) and cIsFloating(dst_type)) { | 2366 | if (!cIsFloating(src_type) and cIsFloating(dst_type)) { |
| 2367 | var rhs = expr; | ||
| 2368 | if (qualTypeIsBoolean(src_type)) rhs = try Tag.bool_to_int.create(c.arena, expr); | ||
| 2361 | // @intToFloat(dest_type, val) | 2369 | // @intToFloat(dest_type, val) |
| 2362 | return Tag.int_to_float.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 2370 | return Tag.int_to_float.create(c.arena, .{ .lhs = dst_node, .rhs = rhs }); |
| 2363 | } | 2371 | } |
| 2364 | if (qualTypeIsBoolean(src_type) and !qualTypeIsBoolean(dst_type)) { | 2372 | if (qualTypeIsBoolean(src_type) and !qualTypeIsBoolean(dst_type)) { |
| 2365 | // @boolToInt returns either a comptime_int or a u1 | 2373 | // @boolToInt returns either a comptime_int or a u1 |
| ... | @@ -2370,7 +2378,7 @@ fn transCCast( | ... | @@ -2370,7 +2378,7 @@ fn transCCast( |
| 2370 | } | 2378 | } |
| 2371 | if (cIsEnum(dst_type)) { | 2379 | if (cIsEnum(dst_type)) { |
| 2372 | // import("std").meta.cast(dest_type, val) | 2380 | // import("std").meta.cast(dest_type, val) |
| 2373 | return Tag.std_meta_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); | 2381 | return Tag.helpers_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); |
| 2374 | } | 2382 | } |
| 2375 | if (cIsEnum(src_type) and !cIsEnum(dst_type)) { | 2383 | if (cIsEnum(src_type) and !cIsEnum(dst_type)) { |
| 2376 | // @enumToInt(val) | 2384 | // @enumToInt(val) |
| ... | @@ -4547,6 +4555,10 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan | ... | @@ -4547,6 +4555,10 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan |
| 4547 | .rhs = try transQualType(c, scope, element_qt, source_loc), | 4555 | .rhs = try transQualType(c, scope, element_qt, source_loc), |
| 4548 | }); | 4556 | }); |
| 4549 | }, | 4557 | }, |
| 4558 | .ExtInt, .ExtVector => { | ||
| 4559 | const type_name = c.str(ty.getTypeClassName()); | ||
| 4560 | return fail(c, error.UnsupportedType, source_loc, "TODO implement translation of type: '{s}'", .{type_name}); | ||
| 4561 | }, | ||
| 4550 | else => { | 4562 | else => { |
| 4551 | const type_name = c.str(ty.getTypeClassName()); | 4563 | const type_name = c.str(ty.getTypeClassName()); |
| 4552 | return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{type_name}); | 4564 | return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{type_name}); |
| ... | @@ -4982,7 +4994,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -4982,7 +4994,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 4982 | break :blk br.data.val; | 4994 | break :blk br.data.val; |
| 4983 | } else expr; | 4995 | } else expr; |
| 4984 | 4996 | ||
| 4985 | const return_type = if (typeof_arg.castTag(.std_meta_cast) orelse typeof_arg.castTag(.std_mem_zeroinit)) |some| | 4997 | const return_type = if (typeof_arg.castTag(.helpers_cast) orelse typeof_arg.castTag(.std_mem_zeroinit)) |some| |
| 4986 | some.data.lhs | 4998 | some.data.lhs |
| 4987 | else if (typeof_arg.castTag(.std_mem_zeroes)) |some| | 4999 | else if (typeof_arg.castTag(.std_mem_zeroes)) |some| |
| 4988 | some.data | 5000 | some.data |
| ... | @@ -5095,7 +5107,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { | ... | @@ -5095,7 +5107,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { |
| 5095 | if (guaranteed_to_fit) { | 5107 | if (guaranteed_to_fit) { |
| 5096 | return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = literal_node }); | 5108 | return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = literal_node }); |
| 5097 | } else { | 5109 | } else { |
| 5098 | return Tag.std_meta_promoteIntLiteral.create(c.arena, .{ | 5110 | return Tag.helpers_promoteIntLiteral.create(c.arena, .{ |
| 5099 | .type = type_node, | 5111 | .type = type_node, |
| 5100 | .value = literal_node, | 5112 | .value = literal_node, |
| 5101 | .radix = try Tag.enum_literal.create(c.arena, radix), | 5113 | .radix = try Tag.enum_literal.create(c.arena, radix), |
| ... | @@ -5578,7 +5590,7 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5578,7 +5590,7 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5578 | return parseCPostfixExpr(c, m, scope, type_name); | 5590 | return parseCPostfixExpr(c, m, scope, type_name); |
| 5579 | } | 5591 | } |
| 5580 | const node_to_cast = try parseCCastExpr(c, m, scope); | 5592 | const node_to_cast = try parseCCastExpr(c, m, scope); |
| 5581 | return Tag.std_meta_cast.create(c.arena, .{ .lhs = type_name, .rhs = node_to_cast }); | 5593 | return Tag.helpers_cast.create(c.arena, .{ .lhs = type_name, .rhs = node_to_cast }); |
| 5582 | } | 5594 | } |
| 5583 | }, | 5595 | }, |
| 5584 | else => {}, | 5596 | else => {}, |
| ... | @@ -5925,7 +5937,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { | ... | @@ -5925,7 +5937,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node { |
| 5925 | break :blk inner; | 5937 | break :blk inner; |
| 5926 | } else try parseCUnaryExpr(c, m, scope); | 5938 | } else try parseCUnaryExpr(c, m, scope); |
| 5927 | 5939 | ||
| 5928 | return Tag.std_meta_sizeof.create(c.arena, operand); | 5940 | return Tag.helpers_sizeof.create(c.arena, operand); |
| 5929 | }, | 5941 | }, |
| 5930 | .Keyword_alignof => { | 5942 | .Keyword_alignof => { |
| 5931 | // TODO this won't work if using <stdalign.h>'s | 5943 | // TODO this won't work if using <stdalign.h>'s |
src/translate_c/ast.zig+44-43| ... | @@ -74,7 +74,7 @@ pub const Node = extern union { | ... | @@ -74,7 +74,7 @@ pub const Node = extern union { |
| 74 | tuple, | 74 | tuple, |
| 75 | container_init, | 75 | container_init, |
| 76 | container_init_dot, | 76 | container_init_dot, |
| 77 | std_meta_cast, | 77 | helpers_cast, |
| 78 | /// _ = operand; | 78 | /// _ = operand; |
| 79 | discard, | 79 | discard, |
| 80 | 80 | ||
| ... | @@ -124,8 +124,8 @@ pub const Node = extern union { | ... | @@ -124,8 +124,8 @@ pub const Node = extern union { |
| 124 | std_math_Log2Int, | 124 | std_math_Log2Int, |
| 125 | /// @intCast(lhs, rhs) | 125 | /// @intCast(lhs, rhs) |
| 126 | int_cast, | 126 | int_cast, |
| 127 | /// @import("std").meta.promoteIntLiteral(value, type, radix) | 127 | /// @import("std").zig.c_translation.promoteIntLiteral(value, type, radix) |
| 128 | std_meta_promoteIntLiteral, | 128 | helpers_promoteIntLiteral, |
| 129 | /// @import("std").meta.alignment(value) | 129 | /// @import("std").meta.alignment(value) |
| 130 | std_meta_alignment, | 130 | std_meta_alignment, |
| 131 | /// @rem(lhs, rhs) | 131 | /// @rem(lhs, rhs) |
| ... | @@ -193,12 +193,12 @@ pub const Node = extern union { | ... | @@ -193,12 +193,12 @@ pub const Node = extern union { |
| 193 | array_type, | 193 | array_type, |
| 194 | null_sentinel_array_type, | 194 | null_sentinel_array_type, |
| 195 | 195 | ||
| 196 | /// @import("std").meta.sizeof(operand) | 196 | /// @import("std").zig.c_translation.sizeof(operand) |
| 197 | std_meta_sizeof, | 197 | helpers_sizeof, |
| 198 | /// @import("std").meta.FlexibleArrayType(lhs, rhs) | 198 | /// @import("std").zig.c_translation.FlexibleArrayType(lhs, rhs) |
| 199 | std_meta_flexible_array_type, | 199 | helpers_flexible_array_type, |
| 200 | /// @import("std").meta.shuffleVectorIndex(lhs, rhs) | 200 | /// @import("std").zig.c_translation.shuffleVectorIndex(lhs, rhs) |
| 201 | std_meta_shuffle_vector_index, | 201 | helpers_shuffle_vector_index, |
| 202 | /// @import("std").meta.Vector(lhs, rhs) | 202 | /// @import("std").meta.Vector(lhs, rhs) |
| 203 | std_meta_vector, | 203 | std_meta_vector, |
| 204 | /// @import("std").mem.zeroes(operand) | 204 | /// @import("std").mem.zeroes(operand) |
| ... | @@ -272,7 +272,7 @@ pub const Node = extern union { | ... | @@ -272,7 +272,7 @@ pub const Node = extern union { |
| 272 | .if_not_break, | 272 | .if_not_break, |
| 273 | .switch_else, | 273 | .switch_else, |
| 274 | .block_single, | 274 | .block_single, |
| 275 | .std_meta_sizeof, | 275 | .helpers_sizeof, |
| 276 | .std_meta_alignment, | 276 | .std_meta_alignment, |
| 277 | .bool_to_int, | 277 | .bool_to_int, |
| 278 | .sizeof, | 278 | .sizeof, |
| ... | @@ -332,13 +332,13 @@ pub const Node = extern union { | ... | @@ -332,13 +332,13 @@ pub const Node = extern union { |
| 332 | .align_cast, | 332 | .align_cast, |
| 333 | .array_access, | 333 | .array_access, |
| 334 | .std_mem_zeroinit, | 334 | .std_mem_zeroinit, |
| 335 | .std_meta_flexible_array_type, | 335 | .helpers_flexible_array_type, |
| 336 | .std_meta_shuffle_vector_index, | 336 | .helpers_shuffle_vector_index, |
| 337 | .std_meta_vector, | 337 | .std_meta_vector, |
| 338 | .ptr_cast, | 338 | .ptr_cast, |
| 339 | .div_exact, | 339 | .div_exact, |
| 340 | .offset_of, | 340 | .offset_of, |
| 341 | .std_meta_cast, | 341 | .helpers_cast, |
| 342 | => Payload.BinOp, | 342 | => Payload.BinOp, |
| 343 | 343 | ||
| 344 | .integer_literal, | 344 | .integer_literal, |
| ... | @@ -362,7 +362,7 @@ pub const Node = extern union { | ... | @@ -362,7 +362,7 @@ pub const Node = extern union { |
| 362 | .tuple => Payload.TupleInit, | 362 | .tuple => Payload.TupleInit, |
| 363 | .container_init => Payload.ContainerInit, | 363 | .container_init => Payload.ContainerInit, |
| 364 | .container_init_dot => Payload.ContainerInitDot, | 364 | .container_init_dot => Payload.ContainerInitDot, |
| 365 | .std_meta_promoteIntLiteral => Payload.PromoteIntLiteral, | 365 | .helpers_promoteIntLiteral => Payload.PromoteIntLiteral, |
| 366 | .block => Payload.Block, | 366 | .block => Payload.Block, |
| 367 | .c_pointer, .single_pointer => Payload.Pointer, | 367 | .c_pointer, .single_pointer => Payload.Pointer, |
| 368 | .array_type, .null_sentinel_array_type => Payload.Array, | 368 | .array_type, .null_sentinel_array_type => Payload.Array, |
| ... | @@ -868,7 +868,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -868,7 +868,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 868 | // pub usingnamespace @import("std").c.builtins; | 868 | // pub usingnamespace @import("std").c.builtins; |
| 869 | _ = try c.addToken(.keyword_pub, "pub"); | 869 | _ = try c.addToken(.keyword_pub, "pub"); |
| 870 | const usingnamespace_token = try c.addToken(.keyword_usingnamespace, "usingnamespace"); | 870 | const usingnamespace_token = try c.addToken(.keyword_usingnamespace, "usingnamespace"); |
| 871 | const import_node = try renderStdImport(c, "c", "builtins"); | 871 | const import_node = try renderStdImport(c, &.{ "zig", "c_builtins" }); |
| 872 | _ = try c.addToken(.semicolon, ";"); | 872 | _ = try c.addToken(.semicolon, ";"); |
| 873 | 873 | ||
| 874 | return c.addNode(.{ | 874 | return c.addNode(.{ |
| ... | @@ -882,52 +882,52 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { | ... | @@ -882,52 +882,52 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { |
| 882 | }, | 882 | }, |
| 883 | .std_math_Log2Int => { | 883 | .std_math_Log2Int => { |
| 884 | const payload = node.castTag(.std_math_Log2Int).?.data; | 884 | const payload = node.castTag(.std_math_Log2Int).?.data; |
| 885 | const import_node = try renderStdImport(c, "math", "Log2Int"); | 885 | const import_node = try renderStdImport(c, &.{ "math", "Log2Int" }); |
| 886 | return renderCall(c, import_node, &.{payload}); | 886 | return renderCall(c, import_node, &.{payload}); |
| 887 | }, | 887 | }, |
| 888 | .std_meta_cast => { | 888 | .helpers_cast => { |
| 889 | const payload = node.castTag(.std_meta_cast).?.data; | 889 | const payload = node.castTag(.helpers_cast).?.data; |
| 890 | const import_node = try renderStdImport(c, "meta", "cast"); | 890 | const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "cast" }); |
| 891 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); | 891 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); |
| 892 | }, | 892 | }, |
| 893 | .std_meta_promoteIntLiteral => { | 893 | .helpers_promoteIntLiteral => { |
| 894 | const payload = node.castTag(.std_meta_promoteIntLiteral).?.data; | 894 | const payload = node.castTag(.helpers_promoteIntLiteral).?.data; |
| 895 | const import_node = try renderStdImport(c, "meta", "promoteIntLiteral"); | 895 | const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "promoteIntLiteral" }); |
| 896 | return renderCall(c, import_node, &.{ payload.type, payload.value, payload.radix }); | 896 | return renderCall(c, import_node, &.{ payload.type, payload.value, payload.radix }); |
| 897 | }, | 897 | }, |
| 898 | .std_meta_alignment => { | 898 | .std_meta_alignment => { |
| 899 | const payload = node.castTag(.std_meta_alignment).?.data; | 899 | const payload = node.castTag(.std_meta_alignment).?.data; |
| 900 | const import_node = try renderStdImport(c, "meta", "alignment"); | 900 | const import_node = try renderStdImport(c, &.{ "meta", "alignment" }); |
| 901 | return renderCall(c, import_node, &.{payload}); | 901 | return renderCall(c, import_node, &.{payload}); |
| 902 | }, | 902 | }, |
| 903 | .std_meta_sizeof => { | 903 | .helpers_sizeof => { |
| 904 | const payload = node.castTag(.std_meta_sizeof).?.data; | 904 | const payload = node.castTag(.helpers_sizeof).?.data; |
| 905 | const import_node = try renderStdImport(c, "meta", "sizeof"); | 905 | const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "sizeof" }); |
| 906 | return renderCall(c, import_node, &.{payload}); | 906 | return renderCall(c, import_node, &.{payload}); |
| 907 | }, | 907 | }, |
| 908 | .std_mem_zeroes => { | 908 | .std_mem_zeroes => { |
| 909 | const payload = node.castTag(.std_mem_zeroes).?.data; | 909 | const payload = node.castTag(.std_mem_zeroes).?.data; |
| 910 | const import_node = try renderStdImport(c, "mem", "zeroes"); | 910 | const import_node = try renderStdImport(c, &.{ "mem", "zeroes" }); |
| 911 | return renderCall(c, import_node, &.{payload}); | 911 | return renderCall(c, import_node, &.{payload}); |
| 912 | }, | 912 | }, |
| 913 | .std_mem_zeroinit => { | 913 | .std_mem_zeroinit => { |
| 914 | const payload = node.castTag(.std_mem_zeroinit).?.data; | 914 | const payload = node.castTag(.std_mem_zeroinit).?.data; |
| 915 | const import_node = try renderStdImport(c, "mem", "zeroInit"); | 915 | const import_node = try renderStdImport(c, &.{ "mem", "zeroInit" }); |
| 916 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); | 916 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); |
| 917 | }, | 917 | }, |
| 918 | .std_meta_flexible_array_type => { | 918 | .helpers_flexible_array_type => { |
| 919 | const payload = node.castTag(.std_meta_flexible_array_type).?.data; | 919 | const payload = node.castTag(.helpers_flexible_array_type).?.data; |
| 920 | const import_node = try renderStdImport(c, "meta", "FlexibleArrayType"); | 920 | const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "FlexibleArrayType" }); |
| 921 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); | 921 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); |
| 922 | }, | 922 | }, |
| 923 | .std_meta_shuffle_vector_index => { | 923 | .helpers_shuffle_vector_index => { |
| 924 | const payload = node.castTag(.std_meta_shuffle_vector_index).?.data; | 924 | const payload = node.castTag(.helpers_shuffle_vector_index).?.data; |
| 925 | const import_node = try renderStdImport(c, "meta", "shuffleVectorIndex"); | 925 | const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "shuffleVectorIndex" }); |
| 926 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); | 926 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); |
| 927 | }, | 927 | }, |
| 928 | .std_meta_vector => { | 928 | .std_meta_vector => { |
| 929 | const payload = node.castTag(.std_meta_vector).?.data; | 929 | const payload = node.castTag(.std_meta_vector).?.data; |
| 930 | const import_node = try renderStdImport(c, "meta", "Vector"); | 930 | const import_node = try renderStdImport(c, &.{ "meta", "Vector" }); |
| 931 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); | 931 | return renderCall(c, import_node, &.{ payload.lhs, payload.rhs }); |
| 932 | }, | 932 | }, |
| 933 | .call => { | 933 | .call => { |
| ... | @@ -2269,13 +2269,13 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { | ... | @@ -2269,13 +2269,13 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { |
| 2269 | .alignof, | 2269 | .alignof, |
| 2270 | .typeof, | 2270 | .typeof, |
| 2271 | .typeinfo, | 2271 | .typeinfo, |
| 2272 | .std_meta_sizeof, | ||
| 2273 | .std_meta_alignment, | 2272 | .std_meta_alignment, |
| 2274 | .std_meta_cast, | ||
| 2275 | .std_meta_promoteIntLiteral, | ||
| 2276 | .std_meta_vector, | 2273 | .std_meta_vector, |
| 2277 | .std_meta_shuffle_vector_index, | 2274 | .helpers_sizeof, |
| 2278 | .std_meta_flexible_array_type, | 2275 | .helpers_cast, |
| 2276 | .helpers_promoteIntLiteral, | ||
| 2277 | .helpers_shuffle_vector_index, | ||
| 2278 | .helpers_flexible_array_type, | ||
| 2279 | .std_mem_zeroinit, | 2279 | .std_mem_zeroinit, |
| 2280 | .integer_literal, | 2280 | .integer_literal, |
| 2281 | .float_literal, | 2281 | .float_literal, |
| ... | @@ -2442,7 +2442,7 @@ fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: Toke | ... | @@ -2442,7 +2442,7 @@ fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: Toke |
| 2442 | }); | 2442 | }); |
| 2443 | } | 2443 | } |
| 2444 | 2444 | ||
| 2445 | fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex { | 2445 | fn renderStdImport(c: *Context, parts: []const []const u8) !NodeIndex { |
| 2446 | const import_tok = try c.addToken(.builtin, "@import"); | 2446 | const import_tok = try c.addToken(.builtin, "@import"); |
| 2447 | _ = try c.addToken(.l_paren, "("); | 2447 | _ = try c.addToken(.l_paren, "("); |
| 2448 | const std_tok = try c.addToken(.string_literal, "\"std\""); | 2448 | const std_tok = try c.addToken(.string_literal, "\"std\""); |
| ... | @@ -2463,8 +2463,9 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde | ... | @@ -2463,8 +2463,9 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde |
| 2463 | }); | 2463 | }); |
| 2464 | 2464 | ||
| 2465 | var access_chain = import_node; | 2465 | var access_chain = import_node; |
| 2466 | access_chain = try renderFieldAccess(c, access_chain, first); | 2466 | for (parts) |part| { |
| 2467 | access_chain = try renderFieldAccess(c, access_chain, second); | 2467 | access_chain = try renderFieldAccess(c, access_chain, part); |
| 2468 | } | ||
| 2468 | return access_chain; | 2469 | return access_chain; |
| 2469 | } | 2470 | } |
| 2470 | 2471 |
test/translate_c.zig+33-33| ... | @@ -133,7 +133,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -133,7 +133,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 133 | \\ const A = @enumToInt(enum_Foo.A); | 133 | \\ const A = @enumToInt(enum_Foo.A); |
| 134 | \\ const B = @enumToInt(enum_Foo.B); | 134 | \\ const B = @enumToInt(enum_Foo.B); |
| 135 | \\ const C = @enumToInt(enum_Foo.C); | 135 | \\ const C = @enumToInt(enum_Foo.C); |
| 136 | \\ var a: enum_Foo = @import("std").meta.cast(enum_Foo, B); | 136 | \\ var a: enum_Foo = @import("std").zig.c_translation.cast(enum_Foo, B); |
| 137 | \\ { | 137 | \\ { |
| 138 | \\ const enum_Foo = extern enum( | 138 | \\ const enum_Foo = extern enum( |
| 139 | ++ default_enum_type ++ | 139 | ++ default_enum_type ++ |
| ... | @@ -146,7 +146,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -146,7 +146,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 146 | \\ const A_2 = @enumToInt(enum_Foo.A); | 146 | \\ const A_2 = @enumToInt(enum_Foo.A); |
| 147 | \\ const B_3 = @enumToInt(enum_Foo.B); | 147 | \\ const B_3 = @enumToInt(enum_Foo.B); |
| 148 | \\ const C_4 = @enumToInt(enum_Foo.C); | 148 | \\ const C_4 = @enumToInt(enum_Foo.C); |
| 149 | \\ var a_5: enum_Foo = @import("std").meta.cast(enum_Foo, B_3); | 149 | \\ var a_5: enum_Foo = @import("std").zig.c_translation.cast(enum_Foo, B_3); |
| 150 | \\ } | 150 | \\ } |
| 151 | \\} | 151 | \\} |
| 152 | }); | 152 | }); |
| ... | @@ -242,7 +242,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -242,7 +242,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 242 | \\#define MEM_PHYSICAL_TO_K0(x) (void*)((uint32_t)(x) + SYS_BASE_CACHED) | 242 | \\#define MEM_PHYSICAL_TO_K0(x) (void*)((uint32_t)(x) + SYS_BASE_CACHED) |
| 243 | , &[_][]const u8{ | 243 | , &[_][]const u8{ |
| 244 | \\pub inline fn MEM_PHYSICAL_TO_K0(x: anytype) ?*c_void { | 244 | \\pub inline fn MEM_PHYSICAL_TO_K0(x: anytype) ?*c_void { |
| 245 | \\ return @import("std").meta.cast(?*c_void, @import("std").meta.cast(u32, x) + SYS_BASE_CACHED); | 245 | \\ return @import("std").zig.c_translation.cast(?*c_void, @import("std").zig.c_translation.cast(u32, x) + SYS_BASE_CACHED); |
| 246 | \\} | 246 | \\} |
| 247 | }); | 247 | }); |
| 248 | 248 | ||
| ... | @@ -282,8 +282,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -282,8 +282,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 282 | , | 282 | , |
| 283 | \\pub const VALUE = ((((@as(c_int, 1) + (@as(c_int, 2) * @as(c_int, 3))) + (@as(c_int, 4) * @as(c_int, 5))) + @as(c_int, 6)) << @as(c_int, 7)) | @boolToInt(@as(c_int, 8) == @as(c_int, 9)); | 283 | \\pub const VALUE = ((((@as(c_int, 1) + (@as(c_int, 2) * @as(c_int, 3))) + (@as(c_int, 4) * @as(c_int, 5))) + @as(c_int, 6)) << @as(c_int, 7)) | @boolToInt(@as(c_int, 8) == @as(c_int, 9)); |
| 284 | , | 284 | , |
| 285 | \\pub inline fn _AL_READ3BYTES(p: anytype) @TypeOf((@import("std").meta.cast([*c]u8, p).* | ((@import("std").meta.cast([*c]u8, p) + @as(c_int, 1)).* << @as(c_int, 8))) | ((@import("std").meta.cast([*c]u8, p) + @as(c_int, 2)).* << @as(c_int, 16))) { | 285 | \\pub inline fn _AL_READ3BYTES(p: anytype) @TypeOf((@import("std").zig.c_translation.cast([*c]u8, p).* | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 1)).* << @as(c_int, 8))) | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 2)).* << @as(c_int, 16))) { |
| 286 | \\ return (@import("std").meta.cast([*c]u8, p).* | ((@import("std").meta.cast([*c]u8, p) + @as(c_int, 1)).* << @as(c_int, 8))) | ((@import("std").meta.cast([*c]u8, p) + @as(c_int, 2)).* << @as(c_int, 16)); | 286 | \\ return (@import("std").zig.c_translation.cast([*c]u8, p).* | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 1)).* << @as(c_int, 8))) | ((@import("std").zig.c_translation.cast([*c]u8, p) + @as(c_int, 2)).* << @as(c_int, 16)); |
| 287 | \\} | 287 | \\} |
| 288 | }); | 288 | }); |
| 289 | 289 | ||
| ... | @@ -438,17 +438,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -438,17 +438,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 438 | , &[_][]const u8{ | 438 | , &[_][]const u8{ |
| 439 | \\pub const struct_foo = extern struct { | 439 | \\pub const struct_foo = extern struct { |
| 440 | \\ x: c_int align(4), | 440 | \\ x: c_int align(4), |
| 441 | \\ pub fn y(self: anytype) @import("std").meta.FlexibleArrayType(@TypeOf(self), c_int) { | 441 | \\ pub fn y(self: anytype) @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int) { |
| 442 | \\ const Intermediate = @import("std").meta.FlexibleArrayType(@TypeOf(self), u8); | 442 | \\ const Intermediate = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), u8); |
| 443 | \\ const ReturnType = @import("std").meta.FlexibleArrayType(@TypeOf(self), c_int); | 443 | \\ const ReturnType = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int); |
| 444 | \\ return @ptrCast(ReturnType, @alignCast(@alignOf(c_int), @ptrCast(Intermediate, self) + 4)); | 444 | \\ return @ptrCast(ReturnType, @alignCast(@alignOf(c_int), @ptrCast(Intermediate, self) + 4)); |
| 445 | \\ } | 445 | \\ } |
| 446 | \\}; | 446 | \\}; |
| 447 | \\pub const struct_bar = extern struct { | 447 | \\pub const struct_bar = extern struct { |
| 448 | \\ x: c_int align(4), | 448 | \\ x: c_int align(4), |
| 449 | \\ pub fn y(self: anytype) @import("std").meta.FlexibleArrayType(@TypeOf(self), c_int) { | 449 | \\ pub fn y(self: anytype) @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int) { |
| 450 | \\ const Intermediate = @import("std").meta.FlexibleArrayType(@TypeOf(self), u8); | 450 | \\ const Intermediate = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), u8); |
| 451 | \\ const ReturnType = @import("std").meta.FlexibleArrayType(@TypeOf(self), c_int); | 451 | \\ const ReturnType = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int); |
| 452 | \\ return @ptrCast(ReturnType, @alignCast(@alignOf(c_int), @ptrCast(Intermediate, self) + 4)); | 452 | \\ return @ptrCast(ReturnType, @alignCast(@alignOf(c_int), @ptrCast(Intermediate, self) + 4)); |
| 453 | \\ } | 453 | \\ } |
| 454 | \\}; | 454 | \\}; |
| ... | @@ -583,7 +583,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -583,7 +583,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 583 | cases.add("#define hex literal with capital X", | 583 | cases.add("#define hex literal with capital X", |
| 584 | \\#define VAL 0XF00D | 584 | \\#define VAL 0XF00D |
| 585 | , &[_][]const u8{ | 585 | , &[_][]const u8{ |
| 586 | \\pub const VAL = @import("std").meta.promoteIntLiteral(c_int, 0xF00D, .hexadecimal); | 586 | \\pub const VAL = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0xF00D, .hexadecimal); |
| 587 | }); | 587 | }); |
| 588 | 588 | ||
| 589 | cases.add("anonymous struct & unions", | 589 | cases.add("anonymous struct & unions", |
| ... | @@ -1738,7 +1738,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1738,7 +1738,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1738 | \\pub const e = @enumToInt(enum_unnamed_1.e); | 1738 | \\pub const e = @enumToInt(enum_unnamed_1.e); |
| 1739 | \\pub const f = @enumToInt(enum_unnamed_1.f); | 1739 | \\pub const f = @enumToInt(enum_unnamed_1.f); |
| 1740 | \\pub const g = @enumToInt(enum_unnamed_1.g); | 1740 | \\pub const g = @enumToInt(enum_unnamed_1.g); |
| 1741 | \\pub export var h: enum_unnamed_1 = @import("std").meta.cast(enum_unnamed_1, e); | 1741 | \\pub export var h: enum_unnamed_1 = @import("std").zig.c_translation.cast(enum_unnamed_1, e); |
| 1742 | \\const enum_unnamed_2 = extern enum( | 1742 | \\const enum_unnamed_2 = extern enum( |
| 1743 | ++ default_enum_type ++ | 1743 | ++ default_enum_type ++ |
| 1744 | \\) { | 1744 | \\) { |
| ... | @@ -1882,7 +1882,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1882,7 +1882,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1882 | \\typedef struct { int dummy; } NRF_GPIO_Type; | 1882 | \\typedef struct { int dummy; } NRF_GPIO_Type; |
| 1883 | \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) | 1883 | \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) |
| 1884 | , &[_][]const u8{ | 1884 | , &[_][]const u8{ |
| 1885 | \\pub const NRF_GPIO = @import("std").meta.cast([*c]NRF_GPIO_Type, NRF_GPIO_BASE); | 1885 | \\pub const NRF_GPIO = @import("std").zig.c_translation.cast([*c]NRF_GPIO_Type, NRF_GPIO_BASE); |
| 1886 | }); | 1886 | }); |
| 1887 | 1887 | ||
| 1888 | cases.add("basic macro function", | 1888 | cases.add("basic macro function", |
| ... | @@ -2379,7 +2379,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -2379,7 +2379,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2379 | \\ var a = arg_a; | 2379 | \\ var a = arg_a; |
| 2380 | \\ var b = arg_b; | 2380 | \\ var b = arg_b; |
| 2381 | \\ var c = arg_c; | 2381 | \\ var c = arg_c; |
| 2382 | \\ var d: enum_Foo = @import("std").meta.cast(enum_Foo, FooA); | 2382 | \\ var d: enum_Foo = @import("std").zig.c_translation.cast(enum_Foo, FooA); |
| 2383 | \\ var e: c_int = @boolToInt((a != 0) and (b != 0)); | 2383 | \\ var e: c_int = @boolToInt((a != 0) and (b != 0)); |
| 2384 | \\ var f: c_int = @boolToInt((b != 0) and (c != null)); | 2384 | \\ var f: c_int = @boolToInt((b != 0) and (c != null)); |
| 2385 | \\ var g: c_int = @boolToInt((a != 0) and (c != null)); | 2385 | \\ var g: c_int = @boolToInt((a != 0) and (c != null)); |
| ... | @@ -3182,13 +3182,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3182,13 +3182,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3182 | \\#define BAR (void*) a | 3182 | \\#define BAR (void*) a |
| 3183 | \\#define BAZ (uint32_t)(2) | 3183 | \\#define BAZ (uint32_t)(2) |
| 3184 | , &[_][]const u8{ | 3184 | , &[_][]const u8{ |
| 3185 | \\pub inline fn FOO(bar: anytype) @TypeOf(baz(@import("std").meta.cast(?*c_void, baz))) { | 3185 | \\pub inline fn FOO(bar: anytype) @TypeOf(baz(@import("std").zig.c_translation.cast(?*c_void, baz))) { |
| 3186 | \\ return baz(@import("std").meta.cast(?*c_void, baz)); | 3186 | \\ return baz(@import("std").zig.c_translation.cast(?*c_void, baz)); |
| 3187 | \\} | 3187 | \\} |
| 3188 | , | 3188 | , |
| 3189 | \\pub const BAR = @import("std").meta.cast(?*c_void, a); | 3189 | \\pub const BAR = @import("std").zig.c_translation.cast(?*c_void, a); |
| 3190 | , | 3190 | , |
| 3191 | \\pub const BAZ = @import("std").meta.cast(u32, @as(c_int, 2)); | 3191 | \\pub const BAZ = @import("std").zig.c_translation.cast(u32, @as(c_int, 2)); |
| 3192 | }); | 3192 | }); |
| 3193 | 3193 | ||
| 3194 | cases.add("macro with cast to unsigned short, long, and long long", | 3194 | cases.add("macro with cast to unsigned short, long, and long long", |
| ... | @@ -3196,9 +3196,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3196,9 +3196,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3196 | \\#define CURLAUTH_BASIC ((unsigned long) 1) | 3196 | \\#define CURLAUTH_BASIC ((unsigned long) 1) |
| 3197 | \\#define CURLAUTH_BASIC_BUT_ULONGLONG ((unsigned long long) 1) | 3197 | \\#define CURLAUTH_BASIC_BUT_ULONGLONG ((unsigned long long) 1) |
| 3198 | , &[_][]const u8{ | 3198 | , &[_][]const u8{ |
| 3199 | \\pub const CURLAUTH_BASIC_BUT_USHORT = @import("std").meta.cast(c_ushort, @as(c_int, 1)); | 3199 | \\pub const CURLAUTH_BASIC_BUT_USHORT = @import("std").zig.c_translation.cast(c_ushort, @as(c_int, 1)); |
| 3200 | \\pub const CURLAUTH_BASIC = @import("std").meta.cast(c_ulong, @as(c_int, 1)); | 3200 | \\pub const CURLAUTH_BASIC = @import("std").zig.c_translation.cast(c_ulong, @as(c_int, 1)); |
| 3201 | \\pub const CURLAUTH_BASIC_BUT_ULONGLONG = @import("std").meta.cast(c_ulonglong, @as(c_int, 1)); | 3201 | \\pub const CURLAUTH_BASIC_BUT_ULONGLONG = @import("std").zig.c_translation.cast(c_ulonglong, @as(c_int, 1)); |
| 3202 | }); | 3202 | }); |
| 3203 | 3203 | ||
| 3204 | cases.add("macro conditional operator", | 3204 | cases.add("macro conditional operator", |
| ... | @@ -3413,8 +3413,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3413,8 +3413,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3413 | \\#define DefaultScreen(dpy) (((_XPrivDisplay)(dpy))->default_screen) | 3413 | \\#define DefaultScreen(dpy) (((_XPrivDisplay)(dpy))->default_screen) |
| 3414 | \\ | 3414 | \\ |
| 3415 | , &[_][]const u8{ | 3415 | , &[_][]const u8{ |
| 3416 | \\pub inline fn DefaultScreen(dpy: anytype) @TypeOf(@import("std").meta.cast(_XPrivDisplay, dpy).*.default_screen) { | 3416 | \\pub inline fn DefaultScreen(dpy: anytype) @TypeOf(@import("std").zig.c_translation.cast(_XPrivDisplay, dpy).*.default_screen) { |
| 3417 | \\ return @import("std").meta.cast(_XPrivDisplay, dpy).*.default_screen; | 3417 | \\ return @import("std").zig.c_translation.cast(_XPrivDisplay, dpy).*.default_screen; |
| 3418 | \\} | 3418 | \\} |
| 3419 | }); | 3419 | }); |
| 3420 | 3420 | ||
| ... | @@ -3422,9 +3422,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3422,9 +3422,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3422 | \\#define NULL ((void*)0) | 3422 | \\#define NULL ((void*)0) |
| 3423 | \\#define FOO ((int)0x8000) | 3423 | \\#define FOO ((int)0x8000) |
| 3424 | , &[_][]const u8{ | 3424 | , &[_][]const u8{ |
| 3425 | \\pub const NULL = @import("std").meta.cast(?*c_void, @as(c_int, 0)); | 3425 | \\pub const NULL = @import("std").zig.c_translation.cast(?*c_void, @as(c_int, 0)); |
| 3426 | , | 3426 | , |
| 3427 | \\pub const FOO = @import("std").meta.cast(c_int, @import("std").meta.promoteIntLiteral(c_int, 0x8000, .hexadecimal)); | 3427 | \\pub const FOO = @import("std").zig.c_translation.cast(c_int, @import("std").zig.c_translation.promoteIntLiteral(c_int, 0x8000, .hexadecimal)); |
| 3428 | }); | 3428 | }); |
| 3429 | 3429 | ||
| 3430 | if (std.Target.current.abi == .msvc) { | 3430 | if (std.Target.current.abi == .msvc) { |
| ... | @@ -3503,11 +3503,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3503,11 +3503,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3503 | \\pub const GUARANTEED_TO_FIT_1 = @as(c_int, 1024); | 3503 | \\pub const GUARANTEED_TO_FIT_1 = @as(c_int, 1024); |
| 3504 | \\pub const GUARANTEED_TO_FIT_2 = @as(c_long, 10241024); | 3504 | \\pub const GUARANTEED_TO_FIT_2 = @as(c_long, 10241024); |
| 3505 | \\pub const GUARANTEED_TO_FIT_3 = @as(c_ulong, 20482048); | 3505 | \\pub const GUARANTEED_TO_FIT_3 = @as(c_ulong, 20482048); |
| 3506 | \\pub const MAY_NEED_PROMOTION_1 = @import("std").meta.promoteIntLiteral(c_int, 10241024, .decimal); | 3506 | \\pub const MAY_NEED_PROMOTION_1 = @import("std").zig.c_translation.promoteIntLiteral(c_int, 10241024, .decimal); |
| 3507 | \\pub const MAY_NEED_PROMOTION_2 = @import("std").meta.promoteIntLiteral(c_long, 307230723072, .decimal); | 3507 | \\pub const MAY_NEED_PROMOTION_2 = @import("std").zig.c_translation.promoteIntLiteral(c_long, 307230723072, .decimal); |
| 3508 | \\pub const MAY_NEED_PROMOTION_3 = @import("std").meta.promoteIntLiteral(c_ulong, 819281928192, .decimal); | 3508 | \\pub const MAY_NEED_PROMOTION_3 = @import("std").zig.c_translation.promoteIntLiteral(c_ulong, 819281928192, .decimal); |
| 3509 | \\pub const MAY_NEED_PROMOTION_HEX = @import("std").meta.promoteIntLiteral(c_int, 0x80000000, .hexadecimal); | 3509 | \\pub const MAY_NEED_PROMOTION_HEX = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0x80000000, .hexadecimal); |
| 3510 | \\pub const MAY_NEED_PROMOTION_OCT = @import("std").meta.promoteIntLiteral(c_int, 0o20000000000, .octal); | 3510 | \\pub const MAY_NEED_PROMOTION_OCT = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0o20000000000, .octal); |
| 3511 | }); | 3511 | }); |
| 3512 | 3512 | ||
| 3513 | // See __builtin_alloca_with_align comment in std.c.builtins | 3513 | // See __builtin_alloca_with_align comment in std.c.builtins |
| ... | @@ -3642,7 +3642,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3642,7 +3642,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3642 | \\typedef long long LONG_PTR; | 3642 | \\typedef long long LONG_PTR; |
| 3643 | \\#define INVALID_HANDLE_VALUE ((void *)(LONG_PTR)-1) | 3643 | \\#define INVALID_HANDLE_VALUE ((void *)(LONG_PTR)-1) |
| 3644 | , &[_][]const u8{ | 3644 | , &[_][]const u8{ |
| 3645 | \\pub const MAP_FAILED = @import("std").meta.cast(?*c_void, -@as(c_int, 1)); | 3645 | \\pub const MAP_FAILED = @import("std").zig.c_translation.cast(?*c_void, -@as(c_int, 1)); |
| 3646 | \\pub const INVALID_HANDLE_VALUE = @import("std").meta.cast(?*c_void, @import("std").meta.cast(LONG_PTR, -@as(c_int, 1))); | 3646 | \\pub const INVALID_HANDLE_VALUE = @import("std").zig.c_translation.cast(?*c_void, @import("std").zig.c_translation.cast(LONG_PTR, -@as(c_int, 1))); |
| 3647 | }); | 3647 | }); |
| 3648 | } | 3648 | } |