Commit 9206f8a8cd

Vexu <git@vexu.eu>
2020-02-14 12:37:39
translate-c improve macro cast translation
1 parent 7396b14
Changed files (2)
src-self-hosted
test
src-self-hosted/translate_c.zig
@@ -5341,12 +5341,27 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
         .LParen => {
             const inner_node = try parseCExpr(c, it, source, source_loc, scope);
 
-            if (it.peek().?.id == .RParen) {
-                _ = it.next();
-                if (it.peek().?.id != .LParen) {
-                    return inner_node;
-                }
-                _ = it.next();
+            if (it.next().?.id != .RParen) {
+                const first_tok = it.list.at(0);
+                try failDecl(
+                    c,
+                    source_loc,
+                    source[first_tok.start..first_tok.end],
+                    "unable to translate C expr: expected ')'' here",
+                    .{},
+                );
+                return error.ParseError;
+            }
+            var saw_l_paren = false;
+            switch (it.peek().?.id) {
+                // (type)(to_cast)
+                .LParen => {
+                    saw_l_paren = true;
+                    _ = it.next();
+                },
+                // (type)identifier
+                .Identifier => {},
+                else => return inner_node,
             }
 
             // hack to get zig fmt to render a comma in builtin calls
@@ -5354,7 +5369,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
 
             const node_to_cast = try parseCExpr(c, it, source, source_loc, scope);
 
-            if (it.next().?.id != .RParen) {
+            if (saw_l_paren and it.next().?.id != .RParen) {
                 const first_tok = it.list.at(0);
                 try failDecl(
                     c,
test/translate_c.zig
@@ -2538,10 +2538,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
 
     cases.add("macro cast",
         \\#define FOO(bar) baz((void *)(baz))
+        \\#define BAR (void*) a
     , &[_][]const u8{
         \\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz))) {
         \\    return baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz));
         \\}
+    ,
+        \\pub const BAR = if (@typeId(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeId(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a);
     });
 
     cases.add("macro conditional operator",