authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-10 12:58:12+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-09-10 13:04:03+03:00
log0833c8d06ba9a467bb8449cbca2ba6f43d218c32
tree933fa529ac107e5c1d9fc77ac3afba493cf747f4
parent78baa16da020ec9ad741b8f3f9c6168ec77ef58d
signaturelock-open Commit is signed but in an unrecognized format.

translate-c: support sizeof and _Alignof in macros

Closes #6301

3 files changed, 49 insertions(+), 2 deletions(-)

src-self-hosted/translate_c.zig+38
...@@ -5899,6 +5899,10 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.N...@@ -5899,6 +5899,10 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.N
5899 saw_l_paren = true;5899 saw_l_paren = true;
5900 _ = m.next();5900 _ = m.next();
5901 },5901 },
5902 // (type)sizeof(x)
5903 .Keyword_sizeof,
5904 // (type)alignof(x)
5905 .Keyword_alignof,
5902 // (type)identifier5906 // (type)identifier
5903 .Identifier => {},5907 .Identifier => {},
5904 // (type)integer5908 // (type)integer
...@@ -6309,6 +6313,40 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast....@@ -6309,6 +6313,40 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.
6309 node.rhs = try parseCPrefixOpExpr(c, m, scope);6313 node.rhs = try parseCPrefixOpExpr(c, m, scope);
6310 return &node.base;6314 return &node.base;
6311 },6315 },
6316 .Keyword_sizeof => {
6317 const inner = if (m.peek().? == .LParen) blk: {
6318 _ = m.next();
6319 const inner = try parseCExpr(c, m, scope);
6320 if (m.next().? != .RParen) {
6321 try m.fail(c, "unable to translate C expr: expected ')'", .{});
6322 return error.ParseError;
6323 }
6324 break :blk inner;
6325 } else try parseCPrefixOpExpr(c, m, scope);
6326
6327 const builtin_call = try c.createBuiltinCall("@sizeOf", 1);
6328 builtin_call.params()[0] = inner;
6329 builtin_call.rparen_token = try appendToken(c, .RParen, ")");
6330 return &builtin_call.base;
6331 },
6332 .Keyword_alignof => {
6333 // TODO this won't work if using <stdalign.h>'s
6334 // #define alignof _Alignof
6335 if (m.next().? != .LParen) {
6336 try m.fail(c, "unable to translate C expr: expected '('", .{});
6337 return error.ParseError;
6338 }
6339 const inner = try parseCExpr(c, m, scope);
6340 if (m.next().? != .RParen) {
6341 try m.fail(c, "unable to translate C expr: expected ')'", .{});
6342 return error.ParseError;
6343 }
6344
6345 const builtin_call = try c.createBuiltinCall("@alignOf", 1);
6346 builtin_call.params()[0] = inner;
6347 builtin_call.rparen_token = try appendToken(c, .RParen, ")");
6348 return &builtin_call.base;
6349 },
6312 else => {6350 else => {
6313 m.i -= 1;6351 m.i -= 1;
6314 return try parseCSuffixOpExpr(c, m, scope);6352 return try parseCSuffixOpExpr(c, m, scope);
test/stage1/behavior/translate_c_macros.h+4-1
...@@ -6,4 +6,7 @@ typedef struct Color {...@@ -6,4 +6,7 @@ typedef struct Color {
6 unsigned char a;6 unsigned char a;
7} Color;7} Color;
8#define CLITERAL(type) (type)8#define CLITERAL(type) (type)
9#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray
\ No newline at end of file
9#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray
10
11#define MY_SIZEOF(x) ((int)sizeof(x))
12#define MY_SIZEOF2(x) ((int)sizeof x)
test/stage1/behavior/translate_c_macros.zig+7-1
...@@ -1,12 +1,18 @@...@@ -1,12 +1,18 @@
1const expect = @import("std").testing.expect;1const expect = @import("std").testing.expect;
2const expectEqual = @import("std").testing.expectEqual;
23
3const h = @cImport(@cInclude("stage1/behavior/translate_c_macros.h"));4const h = @cImport(@cInclude("stage1/behavior/translate_c_macros.h"));
45
5test "initializer list expression" {6test "initializer list expression" {
6 @import("std").testing.expectEqual(h.Color{7 expectEqual(h.Color{
7 .r = 200,8 .r = 200,
8 .g = 200,9 .g = 200,
9 .b = 200,10 .b = 200,
10 .a = 255,11 .a = 255,
11 }, h.LIGHTGRAY);12 }, h.LIGHTGRAY);
12}13}
14
15test "sizeof in macros" {
16 expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
17 expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
18}