diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index a65c1b9fb4..cd42e8abee 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -5899,6 +5899,10 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.N saw_l_paren = true; _ = m.next(); }, + // (type)sizeof(x) + .Keyword_sizeof, + // (type)alignof(x) + .Keyword_alignof, // (type)identifier .Identifier => {}, // (type)integer @@ -6309,6 +6313,40 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast. node.rhs = try parseCPrefixOpExpr(c, m, scope); return &node.base; }, + .Keyword_sizeof => { + const inner = if (m.peek().? == .LParen) blk: { + _ = m.next(); + const inner = try parseCExpr(c, m, scope); + if (m.next().? != .RParen) { + try m.fail(c, "unable to translate C expr: expected ')'", .{}); + return error.ParseError; + } + break :blk inner; + } else try parseCPrefixOpExpr(c, m, scope); + + const builtin_call = try c.createBuiltinCall("@sizeOf", 1); + builtin_call.params()[0] = inner; + builtin_call.rparen_token = try appendToken(c, .RParen, ")"); + return &builtin_call.base; + }, + .Keyword_alignof => { + // TODO this won't work if using 's + // #define alignof _Alignof + if (m.next().? != .LParen) { + try m.fail(c, "unable to translate C expr: expected '('", .{}); + return error.ParseError; + } + const inner = try parseCExpr(c, m, scope); + if (m.next().? != .RParen) { + try m.fail(c, "unable to translate C expr: expected ')'", .{}); + return error.ParseError; + } + + const builtin_call = try c.createBuiltinCall("@alignOf", 1); + builtin_call.params()[0] = inner; + builtin_call.rparen_token = try appendToken(c, .RParen, ")"); + return &builtin_call.base; + }, else => { m.i -= 1; return try parseCSuffixOpExpr(c, m, scope); diff --git a/test/stage1/behavior/translate_c_macros.h b/test/stage1/behavior/translate_c_macros.h index abc6c1e3cf..49806a524e 100644 --- a/test/stage1/behavior/translate_c_macros.h +++ b/test/stage1/behavior/translate_c_macros.h @@ -6,4 +6,7 @@ typedef struct Color { unsigned char a; } Color; #define CLITERAL(type) (type) -#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray \ No newline at end of file +#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray + +#define MY_SIZEOF(x) ((int)sizeof(x)) +#define MY_SIZEOF2(x) ((int)sizeof x) diff --git a/test/stage1/behavior/translate_c_macros.zig b/test/stage1/behavior/translate_c_macros.zig index ea42016e9b..2cfb2331fa 100644 --- a/test/stage1/behavior/translate_c_macros.zig +++ b/test/stage1/behavior/translate_c_macros.zig @@ -1,12 +1,18 @@ const expect = @import("std").testing.expect; +const expectEqual = @import("std").testing.expectEqual; const h = @cImport(@cInclude("stage1/behavior/translate_c_macros.h")); test "initializer list expression" { - @import("std").testing.expectEqual(h.Color{ + expectEqual(h.Color{ .r = 200, .g = 200, .b = 200, .a = 255, }, h.LIGHTGRAY); } + +test "sizeof in macros" { + expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32)); + expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32)); +}