Commit 7b32062775

LordMZTE <lord@mzte.de>
2022-06-29 16:03:29
translate-c: fix cast or call macro with parenthesis
1 parent 234ccb4
src/translate_c.zig
@@ -5110,6 +5110,7 @@ const PatternList = struct {
         [2][]const u8{ "ULL_SUFFIX(X) (X ## ULL)", "ULL_SUFFIX" },
 
         [2][]const u8{ "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL" },
+        [2][]const u8{ "CAST_OR_CALL(X, Y) ((X)(Y))", "CAST_OR_CALL" },
 
         [2][]const u8{
             \\wl_container_of(ptr, sample, member)                     \
@@ -5303,6 +5304,7 @@ test "Macro matching" {
 
     try helper.checkMacro(allocator, pattern_list, "NO_MATCH(X, Y) (X + Y)", null);
     try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) (X)(Y)", "CAST_OR_CALL");
+    try helper.checkMacro(allocator, pattern_list, "CAST_OR_CALL(X, Y) ((X)(Y))", "CAST_OR_CALL");
     try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (void)(X)", "DISCARD");
     try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((void)(X))", "DISCARD");
     try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) (const void)(X)", "DISCARD");
test/behavior/translate_c_macros.h
@@ -37,5 +37,6 @@ union U {
 #define IGNORE_ME_10(x) (volatile const void)(x)
 
 #define UNION_CAST(X) (union U)(X)
+#define CAST_OR_CALL_WITH_PARENS(type_or_fn, val) ((type_or_fn)(val))
 
 #define NESTED_COMMA_OPERATOR (1, (2, 3))
test/behavior/translate_c_macros.zig
@@ -70,6 +70,26 @@ test "casting to union with a macro" {
     try expect(d == casted.d);
 }
 
+test "casting or calling a value with a paren-surrounded macro" {
+    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+
+    const l: c_long = 42;
+    const casted = h.CAST_OR_CALL_WITH_PARENS(c_int, l);
+    try expect(casted == @intCast(c_int, l));
+
+    const Helper = struct {
+        fn foo(n: c_int) !void {
+            try expect(n == 42);
+        }
+    };
+
+    try h.CAST_OR_CALL_WITH_PARENS(Helper.foo, 42);
+}
+
 test "nested comma operator" {
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO