authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-14 23:53:38+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-14 23:53:38+03:00
loga3624e94f812efaae40d2ca66da0b49ca63cb936
tree0b61ed0ac590fd166472864335dac8a659e730ba
parent29fd0c6d61d1569c1691fc5489d51311207b1759
signaturelock-open Commit is signed but in an unrecognized format.

translate-c: determine sizeof using std.meta.sizeof


2 files changed, 43 insertions(+), 4 deletions(-)

lib/std/meta.zig+31
...@@ -795,3 +795,34 @@ test "std.meta.cast" {...@@ -795,3 +795,34 @@ test "std.meta.cast" {
795 testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10)));795 testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10)));
796 testing.expectEqual(@as(u8, 2), cast(u8, E.Two));796 testing.expectEqual(@as(u8, 2), cast(u8, E.Two));
797}797}
798
799/// Given a value returns its size as C's sizeof operator would.
800/// This is for translate-c and is not intended for general use.
801pub fn sizeof(target: anytype) usize {
802 switch (@typeInfo(@TypeOf(target))) {
803 .Type => return @sizeOf(target),
804 .Float, .Int, .Struct, .Union, .Enum => return @sizeOf(@TypeOf(target)),
805 .ComptimeFloat => return @sizeOf(f64), // TODO c_double #3999
806 .ComptimeInt => {
807 // TODO to get the correct result we have to translate
808 // `1073741824 * 4` as `int(1073741824) *% int(4)` since
809 // sizeof(1073741824 * 4) != sizeof(4294967296).
810
811 // TODO test if target fits in int, long or long long
812 return @sizeOf(c_int);
813 },
814 else => @compileError("TODO implement std.meta.sizeof for type " ++ @typeName(@TypeOf(target))),
815 }
816}
817
818test "sizeof" {
819 const E = extern enum(c_int) { One, _ };
820 const S = extern struct { a: u32 };
821
822 testing.expect(sizeof(u32) == 4);
823 testing.expect(sizeof(@as(u32, 2)) == 4);
824 testing.expect(sizeof(2) == @sizeOf(c_int));
825 testing.expect(sizeof(E) == @sizeOf(c_int));
826 testing.expect(sizeof(E.One) == @sizeOf(c_int));
827 testing.expect(sizeof(S) == 4);
828}
src-self-hosted/translate_c.zig+12-4
...@@ -6324,10 +6324,18 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast....@@ -6324,10 +6324,18 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.
6324 break :blk inner;6324 break :blk inner;
6325 } else try parseCPrefixOpExpr(c, m, scope);6325 } else try parseCPrefixOpExpr(c, m, scope);
63266326
6327 const builtin_call = try c.createBuiltinCall("@sizeOf", 1);6327 //(@import("std").meta.sizeof(dest, x))
6328 builtin_call.params()[0] = inner;6328 const import_fn_call = try c.createBuiltinCall("@import", 1);
6329 builtin_call.rparen_token = try appendToken(c, .RParen, ")");6329 const std_node = try transCreateNodeStringLiteral(c, "\"std\"");
6330 return &builtin_call.base;6330 import_fn_call.params()[0] = std_node;
6331 import_fn_call.rparen_token = try appendToken(c, .RParen, ")");
6332 const inner_field_access = try transCreateNodeFieldAccess(c, &import_fn_call.base, "meta");
6333 const outer_field_access = try transCreateNodeFieldAccess(c, inner_field_access, "sizeof");
6334
6335 const sizeof_call = try c.createCall(outer_field_access, 1);
6336 sizeof_call.params()[0] = inner;
6337 sizeof_call.rtoken = try appendToken(c, .RParen, ")");
6338 return &sizeof_call.base;
6331 },6339 },
6332 .Keyword_alignof => {6340 .Keyword_alignof => {
6333 // TODO this won't work if using <stdalign.h>'s6341 // TODO this won't work if using <stdalign.h>'s