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;
1010pub const tokenizer = @import("c/tokenizer.zig");
1111pub const Token = tokenizer.Token;
1212pub const Tokenizer = tokenizer.Tokenizer;
13pub const builtins = @import("c/builtins.zig");
1413
1514test {
1615 _ = 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 {
884884 });
885885}
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
1200887/// For a given function type, returns a tuple type which fields will
1201888/// correspond to the argument types.
1202889///
......@@ -1316,38 +1003,6 @@ pub fn globalOption(comptime name: []const u8, comptime T: type) ?T {
13161003 return @as(T, @field(root, name));
13171004}
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
13511006/// Returns whether `error_union` contains an error.
13521007pub fn isError(error_union: anytype) bool {
13531008 return if (error_union) |_| false else |_| true;
......@@ -1357,34 +1012,3 @@ test "isError" {
13571012 try std.testing.expect(isError(math.absInt(@as(i8, -128))));
13581013 try std.testing.expect(!isError(math.absInt(@as(i8, -127))));
13591014}
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");
1616pub const system = @import("zig/system.zig");
1717pub 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
1923pub const SrcHash = [16]u8;
2024
2125pub 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;
1212const ast = @import("translate_c/ast.zig");
1313const Node = ast.Node;
1414const Tag = Node.Tag;
15const c_builtins = std.c.builtins;
1615
1716const CallingConvention = std.builtin.CallingConvention;
1817
......@@ -863,7 +862,7 @@ fn buildFlexibleArrayFn(
863862 defer block_scope.deinit();
864863
865864 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 });
867866 const intermediate_type_decl = try Tag.var_simple.create(c.arena, .{
868867 .name = intermediate_type_name,
869868 .init = intermediate_type,
......@@ -872,7 +871,7 @@ fn buildFlexibleArrayFn(
872871 const intermediate_type_ident = try Tag.identifier.create(c.arena, intermediate_type_name);
873872
874873 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 });
876875 const return_type_decl = try Tag.var_simple.create(c.arena, .{
877876 .name = return_type_name,
878877 .init = return_type,
......@@ -1290,9 +1289,19 @@ fn transStmt(
12901289 return maybeSuppressResult(c, scope, result_used, shuffle_vec_node);
12911290 },
12921291 // When adding new cases here, see comment for maybeBlockify()
1293 else => {
1294 return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "TODO implement translation of stmt class {s}", .{@tagName(sc)});
1295 },
1292 .GCCAsmStmtClass,
1293 .GotoStmtClass,
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)}),
12961305 }
12971306}
12981307
......@@ -1374,7 +1383,7 @@ fn makeShuffleMask(c: *Context, scope: *Scope, expr: *const clang.ShuffleVectorE
13741383
13751384 for (init_list) |*init, i| {
13761385 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 });
13781387 init.* = converted_index;
13791388 }
13801389
......@@ -1820,13 +1829,10 @@ fn transDeclStmtOne(
18201829 .Function => {
18211830 try visitFnDecl(c, @ptrCast(*const clang.FunctionDecl, decl));
18221831 },
1823 else => |kind| return fail(
1824 c,
1825 error.UnsupportedTranslation,
1826 decl.getLocation(),
1827 "TODO implement translation of DeclStmt kind {s}",
1828 .{@tagName(kind)},
1829 ),
1832 else => {
1833 const decl_name = try c.str(decl.getDeclKindName());
1834 try warn(c, &c.global_scope.base, decl.getLocation(), "ignoring {s} declaration", .{decl_name});
1835 },
18301836 }
18311837}
18321838
......@@ -1902,7 +1908,7 @@ fn transImplicitCastExpr(
19021908 const ne = try Tag.not_equal.create(c.arena, .{ .lhs = ptr_to_int, .rhs = Tag.zero_literal.init() });
19031909 return maybeSuppressResult(c, scope, result_used, ne);
19041910 },
1905 .IntegralToBoolean => {
1911 .IntegralToBoolean, .FloatingToBoolean => {
19061912 const sub_expr_node = try transExpr(c, scope, sub_expr, .used);
19071913
19081914 // The expression is already a boolean one, return it as-is
......@@ -1924,14 +1930,14 @@ fn transImplicitCastExpr(
19241930 c,
19251931 error.UnsupportedTranslation,
19261932 @ptrCast(*const clang.Stmt, expr).getBeginLoc(),
1927 "TODO implement translation of CastKind {s}",
1933 "unsupported CastKind {s}",
19281934 .{@tagName(kind)},
19291935 ),
19301936 }
19311937}
19321938
19331939fn isBuiltinDefined(name: []const u8) bool {
1934 inline for (meta.declarations(c_builtins)) |decl| {
1940 inline for (meta.declarations(std.zig.c_builtins)) |decl| {
19351941 if (std.mem.eql(u8, name, decl.name)) return true;
19361942 }
19371943 return false;
......@@ -2358,8 +2364,10 @@ fn transCCast(
23582364 return Tag.float_to_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
23592365 }
23602366 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);
23612369 // @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 });
23632371 }
23642372 if (qualTypeIsBoolean(src_type) and !qualTypeIsBoolean(dst_type)) {
23652373 // @boolToInt returns either a comptime_int or a u1
......@@ -2370,7 +2378,7 @@ fn transCCast(
23702378 }
23712379 if (cIsEnum(dst_type)) {
23722380 // 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 });
23742382 }
23752383 if (cIsEnum(src_type) and !cIsEnum(dst_type)) {
23762384 // @enumToInt(val)
......@@ -4547,6 +4555,10 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan
45474555 .rhs = try transQualType(c, scope, element_qt, source_loc),
45484556 });
45494557 },
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 },
45504562 else => {
45514563 const type_name = c.str(ty.getTypeClassName());
45524564 return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{type_name});
......@@ -4982,7 +4994,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
49824994 break :blk br.data.val;
49834995 } 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|
49864998 some.data.lhs
49874999 else if (typeof_arg.castTag(.std_mem_zeroes)) |some|
49885000 some.data
......@@ -5095,7 +5107,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
50955107 if (guaranteed_to_fit) {
50965108 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = literal_node });
50975109 } else {
5098 return Tag.std_meta_promoteIntLiteral.create(c.arena, .{
5110 return Tag.helpers_promoteIntLiteral.create(c.arena, .{
50995111 .type = type_node,
51005112 .value = literal_node,
51015113 .radix = try Tag.enum_literal.create(c.arena, radix),
......@@ -5578,7 +5590,7 @@ fn parseCCastExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
55785590 return parseCPostfixExpr(c, m, scope, type_name);
55795591 }
55805592 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 });
55825594 }
55835595 },
55845596 else => {},
......@@ -5925,7 +5937,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
59255937 break :blk inner;
59265938 } 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);
59295941 },
59305942 .Keyword_alignof => {
59315943 // 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 {
7474 tuple,
7575 container_init,
7676 container_init_dot,
77 std_meta_cast,
77 helpers_cast,
7878 /// _ = operand;
7979 discard,
8080
......@@ -124,8 +124,8 @@ pub const Node = extern union {
124124 std_math_Log2Int,
125125 /// @intCast(lhs, rhs)
126126 int_cast,
127 /// @import("std").meta.promoteIntLiteral(value, type, radix)
128 std_meta_promoteIntLiteral,
127 /// @import("std").zig.c_translation.promoteIntLiteral(value, type, radix)
128 helpers_promoteIntLiteral,
129129 /// @import("std").meta.alignment(value)
130130 std_meta_alignment,
131131 /// @rem(lhs, rhs)
......@@ -193,12 +193,12 @@ pub const Node = extern union {
193193 array_type,
194194 null_sentinel_array_type,
195195
196 /// @import("std").meta.sizeof(operand)
197 std_meta_sizeof,
198 /// @import("std").meta.FlexibleArrayType(lhs, rhs)
199 std_meta_flexible_array_type,
200 /// @import("std").meta.shuffleVectorIndex(lhs, rhs)
201 std_meta_shuffle_vector_index,
196 /// @import("std").zig.c_translation.sizeof(operand)
197 helpers_sizeof,
198 /// @import("std").zig.c_translation.FlexibleArrayType(lhs, rhs)
199 helpers_flexible_array_type,
200 /// @import("std").zig.c_translation.shuffleVectorIndex(lhs, rhs)
201 helpers_shuffle_vector_index,
202202 /// @import("std").meta.Vector(lhs, rhs)
203203 std_meta_vector,
204204 /// @import("std").mem.zeroes(operand)
......@@ -272,7 +272,7 @@ pub const Node = extern union {
272272 .if_not_break,
273273 .switch_else,
274274 .block_single,
275 .std_meta_sizeof,
275 .helpers_sizeof,
276276 .std_meta_alignment,
277277 .bool_to_int,
278278 .sizeof,
......@@ -332,13 +332,13 @@ pub const Node = extern union {
332332 .align_cast,
333333 .array_access,
334334 .std_mem_zeroinit,
335 .std_meta_flexible_array_type,
336 .std_meta_shuffle_vector_index,
335 .helpers_flexible_array_type,
336 .helpers_shuffle_vector_index,
337337 .std_meta_vector,
338338 .ptr_cast,
339339 .div_exact,
340340 .offset_of,
341 .std_meta_cast,
341 .helpers_cast,
342342 => Payload.BinOp,
343343
344344 .integer_literal,
......@@ -362,7 +362,7 @@ pub const Node = extern union {
362362 .tuple => Payload.TupleInit,
363363 .container_init => Payload.ContainerInit,
364364 .container_init_dot => Payload.ContainerInitDot,
365 .std_meta_promoteIntLiteral => Payload.PromoteIntLiteral,
365 .helpers_promoteIntLiteral => Payload.PromoteIntLiteral,
366366 .block => Payload.Block,
367367 .c_pointer, .single_pointer => Payload.Pointer,
368368 .array_type, .null_sentinel_array_type => Payload.Array,
......@@ -868,7 +868,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
868868 // pub usingnamespace @import("std").c.builtins;
869869 _ = try c.addToken(.keyword_pub, "pub");
870870 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" });
872872 _ = try c.addToken(.semicolon, ";");
873873
874874 return c.addNode(.{
......@@ -882,52 +882,52 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
882882 },
883883 .std_math_Log2Int => {
884884 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" });
886886 return renderCall(c, import_node, &.{payload});
887887 },
888 .std_meta_cast => {
889 const payload = node.castTag(.std_meta_cast).?.data;
890 const import_node = try renderStdImport(c, "meta", "cast");
888 .helpers_cast => {
889 const payload = node.castTag(.helpers_cast).?.data;
890 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "cast" });
891891 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
892892 },
893 .std_meta_promoteIntLiteral => {
894 const payload = node.castTag(.std_meta_promoteIntLiteral).?.data;
895 const import_node = try renderStdImport(c, "meta", "promoteIntLiteral");
893 .helpers_promoteIntLiteral => {
894 const payload = node.castTag(.helpers_promoteIntLiteral).?.data;
895 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "promoteIntLiteral" });
896896 return renderCall(c, import_node, &.{ payload.type, payload.value, payload.radix });
897897 },
898898 .std_meta_alignment => {
899899 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" });
901901 return renderCall(c, import_node, &.{payload});
902902 },
903 .std_meta_sizeof => {
904 const payload = node.castTag(.std_meta_sizeof).?.data;
905 const import_node = try renderStdImport(c, "meta", "sizeof");
903 .helpers_sizeof => {
904 const payload = node.castTag(.helpers_sizeof).?.data;
905 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "sizeof" });
906906 return renderCall(c, import_node, &.{payload});
907907 },
908908 .std_mem_zeroes => {
909909 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" });
911911 return renderCall(c, import_node, &.{payload});
912912 },
913913 .std_mem_zeroinit => {
914914 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" });
916916 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
917917 },
918 .std_meta_flexible_array_type => {
919 const payload = node.castTag(.std_meta_flexible_array_type).?.data;
920 const import_node = try renderStdImport(c, "meta", "FlexibleArrayType");
918 .helpers_flexible_array_type => {
919 const payload = node.castTag(.helpers_flexible_array_type).?.data;
920 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "FlexibleArrayType" });
921921 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
922922 },
923 .std_meta_shuffle_vector_index => {
924 const payload = node.castTag(.std_meta_shuffle_vector_index).?.data;
925 const import_node = try renderStdImport(c, "meta", "shuffleVectorIndex");
923 .helpers_shuffle_vector_index => {
924 const payload = node.castTag(.helpers_shuffle_vector_index).?.data;
925 const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "shuffleVectorIndex" });
926926 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
927927 },
928928 .std_meta_vector => {
929929 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" });
931931 return renderCall(c, import_node, &.{ payload.lhs, payload.rhs });
932932 },
933933 .call => {
......@@ -2269,13 +2269,13 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
22692269 .alignof,
22702270 .typeof,
22712271 .typeinfo,
2272 .std_meta_sizeof,
22732272 .std_meta_alignment,
2274 .std_meta_cast,
2275 .std_meta_promoteIntLiteral,
22762273 .std_meta_vector,
2277 .std_meta_shuffle_vector_index,
2278 .std_meta_flexible_array_type,
2274 .helpers_sizeof,
2275 .helpers_cast,
2276 .helpers_promoteIntLiteral,
2277 .helpers_shuffle_vector_index,
2278 .helpers_flexible_array_type,
22792279 .std_mem_zeroinit,
22802280 .integer_literal,
22812281 .float_literal,
......@@ -2442,7 +2442,7 @@ fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: Toke
24422442 });
24432443}
24442444
2445fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {
2445fn renderStdImport(c: *Context, parts: []const []const u8) !NodeIndex {
24462446 const import_tok = try c.addToken(.builtin, "@import");
24472447 _ = try c.addToken(.l_paren, "(");
24482448 const std_tok = try c.addToken(.string_literal, "\"std\"");
......@@ -2463,8 +2463,9 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde
24632463 });
24642464
24652465 var access_chain = import_node;
2466 access_chain = try renderFieldAccess(c, access_chain, first);
2467 access_chain = try renderFieldAccess(c, access_chain, second);
2466 for (parts) |part| {
2467 access_chain = try renderFieldAccess(c, access_chain, part);
2468 }
24682469 return access_chain;
24692470}
24702471
test/translate_c.zig+33-33
......@@ -133,7 +133,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
133133 \\ const A = @enumToInt(enum_Foo.A);
134134 \\ const B = @enumToInt(enum_Foo.B);
135135 \\ 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);
137137 \\ {
138138 \\ const enum_Foo = extern enum(
139139 ++ default_enum_type ++
......@@ -146,7 +146,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
146146 \\ const A_2 = @enumToInt(enum_Foo.A);
147147 \\ const B_3 = @enumToInt(enum_Foo.B);
148148 \\ 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);
150150 \\ }
151151 \\}
152152 });
......@@ -242,7 +242,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
242242 \\#define MEM_PHYSICAL_TO_K0(x) (void*)((uint32_t)(x) + SYS_BASE_CACHED)
243243 , &[_][]const u8{
244244 \\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);
246246 \\}
247247 });
248248
......@@ -282,8 +282,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
282282 ,
283283 \\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));
284284 ,
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))) {
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));
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").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));
287287 \\}
288288 });
289289
......@@ -438,17 +438,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
438438 , &[_][]const u8{
439439 \\pub const struct_foo = extern struct {
440440 \\ x: c_int align(4),
441 \\ pub fn y(self: anytype) @import("std").meta.FlexibleArrayType(@TypeOf(self), c_int) {
442 \\ const Intermediate = @import("std").meta.FlexibleArrayType(@TypeOf(self), u8);
443 \\ const ReturnType = @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").zig.c_translation.FlexibleArrayType(@TypeOf(self), u8);
443 \\ const ReturnType = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int);
444444 \\ return @ptrCast(ReturnType, @alignCast(@alignOf(c_int), @ptrCast(Intermediate, self) + 4));
445445 \\ }
446446 \\};
447447 \\pub const struct_bar = extern struct {
448448 \\ x: c_int align(4),
449 \\ pub fn y(self: anytype) @import("std").meta.FlexibleArrayType(@TypeOf(self), c_int) {
450 \\ const Intermediate = @import("std").meta.FlexibleArrayType(@TypeOf(self), u8);
451 \\ const ReturnType = @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").zig.c_translation.FlexibleArrayType(@TypeOf(self), u8);
451 \\ const ReturnType = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int);
452452 \\ return @ptrCast(ReturnType, @alignCast(@alignOf(c_int), @ptrCast(Intermediate, self) + 4));
453453 \\ }
454454 \\};
......@@ -583,7 +583,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
583583 cases.add("#define hex literal with capital X",
584584 \\#define VAL 0XF00D
585585 , &[_][]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);
587587 });
588588
589589 cases.add("anonymous struct & unions",
......@@ -1738,7 +1738,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17381738 \\pub const e = @enumToInt(enum_unnamed_1.e);
17391739 \\pub const f = @enumToInt(enum_unnamed_1.f);
17401740 \\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);
17421742 \\const enum_unnamed_2 = extern enum(
17431743 ++ default_enum_type ++
17441744 \\) {
......@@ -1882,7 +1882,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
18821882 \\typedef struct { int dummy; } NRF_GPIO_Type;
18831883 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
18841884 , &[_][]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);
18861886 });
18871887
18881888 cases.add("basic macro function",
......@@ -2379,7 +2379,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
23792379 \\ var a = arg_a;
23802380 \\ var b = arg_b;
23812381 \\ 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);
23832383 \\ var e: c_int = @boolToInt((a != 0) and (b != 0));
23842384 \\ var f: c_int = @boolToInt((b != 0) and (c != null));
23852385 \\ var g: c_int = @boolToInt((a != 0) and (c != null));
......@@ -3182,13 +3182,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
31823182 \\#define BAR (void*) a
31833183 \\#define BAZ (uint32_t)(2)
31843184 , &[_][]const u8{
3185 \\pub inline fn FOO(bar: anytype) @TypeOf(baz(@import("std").meta.cast(?*c_void, baz))) {
3186 \\ return 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").zig.c_translation.cast(?*c_void, baz));
31873187 \\}
31883188 ,
3189 \\pub const BAR = @import("std").meta.cast(?*c_void, a);
3189 \\pub const BAR = @import("std").zig.c_translation.cast(?*c_void, a);
31903190 ,
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));
31923192 });
31933193
31943194 cases.add("macro with cast to unsigned short, long, and long long",
......@@ -3196,9 +3196,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
31963196 \\#define CURLAUTH_BASIC ((unsigned long) 1)
31973197 \\#define CURLAUTH_BASIC_BUT_ULONGLONG ((unsigned long long) 1)
31983198 , &[_][]const u8{
3199 \\pub const CURLAUTH_BASIC_BUT_USHORT = @import("std").meta.cast(c_ushort, @as(c_int, 1));
3200 \\pub const CURLAUTH_BASIC = @import("std").meta.cast(c_ulong, @as(c_int, 1));
3201 \\pub const CURLAUTH_BASIC_BUT_ULONGLONG = @import("std").meta.cast(c_ulonglong, @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").zig.c_translation.cast(c_ulong, @as(c_int, 1));
3201 \\pub const CURLAUTH_BASIC_BUT_ULONGLONG = @import("std").zig.c_translation.cast(c_ulonglong, @as(c_int, 1));
32023202 });
32033203
32043204 cases.add("macro conditional operator",
......@@ -3413,8 +3413,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
34133413 \\#define DefaultScreen(dpy) (((_XPrivDisplay)(dpy))->default_screen)
34143414 \\
34153415 , &[_][]const u8{
3416 \\pub inline fn DefaultScreen(dpy: anytype) @TypeOf(@import("std").meta.cast(_XPrivDisplay, dpy).*.default_screen) {
3417 \\ return @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").zig.c_translation.cast(_XPrivDisplay, dpy).*.default_screen;
34183418 \\}
34193419 });
34203420
......@@ -3422,9 +3422,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
34223422 \\#define NULL ((void*)0)
34233423 \\#define FOO ((int)0x8000)
34243424 , &[_][]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));
34263426 ,
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));
34283428 });
34293429
34303430 if (std.Target.current.abi == .msvc) {
......@@ -3503,11 +3503,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
35033503 \\pub const GUARANTEED_TO_FIT_1 = @as(c_int, 1024);
35043504 \\pub const GUARANTEED_TO_FIT_2 = @as(c_long, 10241024);
35053505 \\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);
3507 \\pub const MAY_NEED_PROMOTION_2 = @import("std").meta.promoteIntLiteral(c_long, 307230723072, .decimal);
3508 \\pub const MAY_NEED_PROMOTION_3 = @import("std").meta.promoteIntLiteral(c_ulong, 819281928192, .decimal);
3509 \\pub const MAY_NEED_PROMOTION_HEX = @import("std").meta.promoteIntLiteral(c_int, 0x80000000, .hexadecimal);
3510 \\pub const MAY_NEED_PROMOTION_OCT = @import("std").meta.promoteIntLiteral(c_int, 0o20000000000, .octal);
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").zig.c_translation.promoteIntLiteral(c_long, 307230723072, .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").zig.c_translation.promoteIntLiteral(c_int, 0x80000000, .hexadecimal);
3510 \\pub const MAY_NEED_PROMOTION_OCT = @import("std").zig.c_translation.promoteIntLiteral(c_int, 0o20000000000, .octal);
35113511 });
35123512
35133513 // See __builtin_alloca_with_align comment in std.c.builtins
......@@ -3642,7 +3642,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
36423642 \\typedef long long LONG_PTR;
36433643 \\#define INVALID_HANDLE_VALUE ((void *)(LONG_PTR)-1)
36443644 , &[_][]const u8{
3645 \\pub const MAP_FAILED = @import("std").meta.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)));
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").zig.c_translation.cast(?*c_void, @import("std").zig.c_translation.cast(LONG_PTR, -@as(c_int, 1)));
36473647 });
36483648}