authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-06-12 21:30:36+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-06-14 20:13:34+03:00
log699b6cdf01babd86d56206667a35491d2c4d00f1
treeddf70f0d6282034497707a579197428740cb3b30
parentec36b82d058b7e20101a2f55a7ec123077ce9b70

translate-c: move utility functions to a separate namespace


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;
10pub const tokenizer = @import("c/tokenizer.zig");10pub const tokenizer = @import("c/tokenizer.zig");
11pub const Token = tokenizer.Token;11pub const Token = tokenizer.Token;
12pub const Tokenizer = tokenizer.Tokenizer;12pub const Tokenizer = tokenizer.Tokenizer;
13pub const builtins = @import("c/builtins.zig");
1413
15test {14test {
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
7const std = @import("std");
8
9pub inline fn __builtin_bswap16(val: u16) u16 {
10 return @byteSwap(u16, val);
11}
12pub inline fn __builtin_bswap32(val: u32) u32 {
13 return @byteSwap(u32, val);
14}
15pub inline fn __builtin_bswap64(val: u64) u64 {
16 return @byteSwap(u64, val);
17}
18
19pub inline fn __builtin_signbit(val: f64) c_int {
20 return @boolToInt(std.math.signbit(val));
21}
22pub inline fn __builtin_signbitf(val: f32) c_int {
23 return @boolToInt(std.math.signbit(val));
24}
25
26pub 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}
31pub 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}
37pub 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
44pub inline fn __builtin_sqrt(val: f64) f64 {
45 return @sqrt(val);
46}
47pub inline fn __builtin_sqrtf(val: f32) f32 {
48 return @sqrt(val);
49}
50
51pub inline fn __builtin_sin(val: f64) f64 {
52 return @sin(val);
53}
54pub inline fn __builtin_sinf(val: f32) f32 {
55 return @sin(val);
56}
57pub inline fn __builtin_cos(val: f64) f64 {
58 return @cos(val);
59}
60pub inline fn __builtin_cosf(val: f32) f32 {
61 return @cos(val);
62}
63
64pub inline fn __builtin_exp(val: f64) f64 {
65 return @exp(val);
66}
67pub inline fn __builtin_expf(val: f32) f32 {
68 return @exp(val);
69}
70pub inline fn __builtin_exp2(val: f64) f64 {
71 return @exp2(val);
72}
73pub inline fn __builtin_exp2f(val: f32) f32 {
74 return @exp2(val);
75}
76pub inline fn __builtin_log(val: f64) f64 {
77 return @log(val);
78}
79pub inline fn __builtin_logf(val: f32) f32 {
80 return @log(val);
81}
82pub inline fn __builtin_log2(val: f64) f64 {
83 return @log2(val);
84}
85pub inline fn __builtin_log2f(val: f32) f32 {
86 return @log2(val);
87}
88pub inline fn __builtin_log10(val: f64) f64 {
89 return @log10(val);
90}
91pub 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.
96pub inline fn __builtin_abs(val: c_int) c_int {
97 return std.math.absInt(val) catch std.math.minInt(c_int);
98}
99pub inline fn __builtin_fabs(val: f64) f64 {
100 return @fabs(val);
101}
102pub inline fn __builtin_fabsf(val: f32) f32 {
103 return @fabs(val);
104}
105
106pub inline fn __builtin_floor(val: f64) f64 {
107 return @floor(val);
108}
109pub inline fn __builtin_floorf(val: f32) f32 {
110 return @floor(val);
111}
112pub inline fn __builtin_ceil(val: f64) f64 {
113 return @ceil(val);
114}
115pub inline fn __builtin_ceilf(val: f32) f32 {
116 return @ceil(val);
117}
118pub inline fn __builtin_trunc(val: f64) f64 {
119 return @trunc(val);
120}
121pub inline fn __builtin_truncf(val: f32) f32 {
122 return @trunc(val);
123}
124pub inline fn __builtin_round(val: f64) f64 {
125 return @round(val);
126}
127pub inline fn __builtin_roundf(val: f32) f32 {
128 return @round(val);
129}
130
131pub inline fn __builtin_strlen(s: [*c]const u8) usize {
132 return std.mem.lenZ(s);
133}
134pub 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
138pub 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
148pub 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
158pub 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
164pub 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
174pub 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.
188pub 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}
886886
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.
889pub 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
929fn 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
939fn 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
952fn 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
976fn 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
984test "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.
1035pub 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
1103test "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
1148pub const CIntLiteralRadix = enum { decimal, octal, hexadecimal };
1149
1150fn 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.
1174pub 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
1182test "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 will887/// 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}
13181005
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
1326pub 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
1335test "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.
1352pub fn isError(error_union: anytype) bool {1007pub 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.
1364pub 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
1381test "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");
16pub const system = @import("zig/system.zig");16pub const system = @import("zig/system.zig");
17pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget;17pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget;
1818
19// Files needed by translate-c.
20pub const c_builtins = @import("zig/c_builtins.zig");
21pub const c_translation = @import("zig/c_translation.zig");
22
19pub const SrcHash = [16]u8;23pub const SrcHash = [16]u8;
2024
21pub fn hashSrc(src: []const u8) SrcHash {25pub 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
7const std = @import("std");
8
9pub inline fn __builtin_bswap16(val: u16) u16 {
10 return @byteSwap(u16, val);
11}
12pub inline fn __builtin_bswap32(val: u32) u32 {
13 return @byteSwap(u32, val);
14}
15pub inline fn __builtin_bswap64(val: u64) u64 {
16 return @byteSwap(u64, val);
17}
18
19pub inline fn __builtin_signbit(val: f64) c_int {
20 return @boolToInt(std.math.signbit(val));
21}
22pub inline fn __builtin_signbitf(val: f32) c_int {
23 return @boolToInt(std.math.signbit(val));
24}
25
26pub 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}
31pub 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}
37pub 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
44pub inline fn __builtin_sqrt(val: f64) f64 {
45 return @sqrt(val);
46}
47pub inline fn __builtin_sqrtf(val: f32) f32 {
48 return @sqrt(val);
49}
50
51pub inline fn __builtin_sin(val: f64) f64 {
52 return @sin(val);
53}
54pub inline fn __builtin_sinf(val: f32) f32 {
55 return @sin(val);
56}
57pub inline fn __builtin_cos(val: f64) f64 {
58 return @cos(val);
59}
60pub inline fn __builtin_cosf(val: f32) f32 {
61 return @cos(val);
62}
63
64pub inline fn __builtin_exp(val: f64) f64 {
65 return @exp(val);
66}
67pub inline fn __builtin_expf(val: f32) f32 {
68 return @exp(val);
69}
70pub inline fn __builtin_exp2(val: f64) f64 {
71 return @exp2(val);
72}
73pub inline fn __builtin_exp2f(val: f32) f32 {
74 return @exp2(val);
75}
76pub inline fn __builtin_log(val: f64) f64 {
77 return @log(val);
78}
79pub inline fn __builtin_logf(val: f32) f32 {
80 return @log(val);
81}
82pub inline fn __builtin_log2(val: f64) f64 {
83 return @log2(val);
84}
85pub inline fn __builtin_log2f(val: f32) f32 {
86 return @log2(val);
87}
88pub inline fn __builtin_log10(val: f64) f64 {
89 return @log10(val);
90}
91pub 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.
96pub inline fn __builtin_abs(val: c_int) c_int {
97 return std.math.absInt(val) catch std.math.minInt(c_int);
98}
99pub inline fn __builtin_fabs(val: f64) f64 {
100 return @fabs(val);
101}
102pub inline fn __builtin_fabsf(val: f32) f32 {
103 return @fabs(val);
104}
105
106pub inline fn __builtin_floor(val: f64) f64 {
107 return @floor(val);
108}
109pub inline fn __builtin_floorf(val: f32) f32 {
110 return @floor(val);
111}
112pub inline fn __builtin_ceil(val: f64) f64 {
113 return @ceil(val);
114}
115pub inline fn __builtin_ceilf(val: f32) f32 {
116 return @ceil(val);
117}
118pub inline fn __builtin_trunc(val: f64) f64 {
119 return @trunc(val);
120}
121pub inline fn __builtin_truncf(val: f32) f32 {
122 return @trunc(val);
123}
124pub inline fn __builtin_round(val: f64) f64 {
125 return @round(val);
126}
127pub inline fn __builtin_roundf(val: f32) f32 {
128 return @round(val);
129}
130
131pub inline fn __builtin_strlen(s: [*c]const u8) usize {
132 return std.mem.lenZ(s);
133}
134pub 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
138pub 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
148pub 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
158pub 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
164pub 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
174pub 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.
188pub 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
7const std = @import("std");
8const testing = std.testing;
9const math = std.math;
10const mem = std.mem;
11
12/// Given a type and value, cast the value to the type as c would.
13pub 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
53fn 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
63fn 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
76fn 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
100fn 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
108test "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.
162pub 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
230test "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
275pub const CIntLiteralRadix = enum { decimal, octal, hexadecimal };
276
277fn 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.
300pub 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
308test "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
332pub 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
341test "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.
359pub 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
376test "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;
12const ast = @import("translate_c/ast.zig");12const ast = @import("translate_c/ast.zig");
13const Node = ast.Node;13const Node = ast.Node;
14const Tag = Node.Tag;14const Tag = Node.Tag;
15const c_builtins = std.c.builtins;
1615
17const CallingConvention = std.builtin.CallingConvention;16const CallingConvention = std.builtin.CallingConvention;
1817
...@@ -863,7 +862,7 @@ fn buildFlexibleArrayFn(...@@ -863,7 +862,7 @@ fn buildFlexibleArrayFn(
863 defer block_scope.deinit();862 defer block_scope.deinit();
864863
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);
873872
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}
12981307
...@@ -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
13741383
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 }
13801389
...@@ -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}
18321838
...@@ -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);
19071913
1908 // The expression is already a boolean one, return it as-is1914 // 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}
19321938
1933fn isBuiltinDefined(name: []const u8) bool {1939fn 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 u12373 // @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;
49844996
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.lhs4998 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.data5000 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);
59275939
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>'s5943 // 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,
8080
...@@ -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,
195195
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,
343343
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, ";");
873873
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}
24442444
2445fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {2445fn 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 });
24642464
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}
24702471
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 });
248248
...@@ -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 });
289289
...@@ -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 0XF00D584 \\#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 });
588588
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 });
18871887
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*) a3182 \\#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 });
31933193
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 });
32033203
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 });
34203420
...@@ -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 });
34293429
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 });
35123512
3513 // See __builtin_alloca_with_align comment in std.c.builtins3513 // 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}