| author | |
| committer | |
| log | 9206f8a8cde9a8c1eafc606fe6b3f4129e233aef |
| tree | 6f442cfa03bcb84124ca9fdeb6eb114a0943914e |
| parent | 7396b144ba72d28d10ee1e089fc8e4f87239a840 |
2 files changed, 25 insertions(+), 7 deletions(-)
src-self-hosted/translate_c.zig+22-7| ... | @@ -5341,12 +5341,27 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, | ... | @@ -5341,12 +5341,27 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5341 | .LParen => { | 5341 | .LParen => { |
| 5342 | const inner_node = try parseCExpr(c, it, source, source_loc, scope); | 5342 | const inner_node = try parseCExpr(c, it, source, source_loc, scope); |
| 5343 | 5343 | ||
| 5344 | if (it.peek().?.id == .RParen) { | 5344 | if (it.next().?.id != .RParen) { |
| 5345 | _ = it.next(); | 5345 | const first_tok = it.list.at(0); |
| 5346 | if (it.peek().?.id != .LParen) { | 5346 | try failDecl( |
| 5347 | return inner_node; | 5347 | c, |
| 5348 | } | 5348 | source_loc, |
| 5349 | _ = it.next(); | 5349 | source[first_tok.start..first_tok.end], |
| 5350 | "unable to translate C expr: expected ')'' here", | ||
| 5351 | .{}, | ||
| 5352 | ); | ||
| 5353 | return error.ParseError; | ||
| 5354 | } | ||
| 5355 | var saw_l_paren = false; | ||
| 5356 | switch (it.peek().?.id) { | ||
| 5357 | // (type)(to_cast) | ||
| 5358 | .LParen => { | ||
| 5359 | saw_l_paren = true; | ||
| 5360 | _ = it.next(); | ||
| 5361 | }, | ||
| 5362 | // (type)identifier | ||
| 5363 | .Identifier => {}, | ||
| 5364 | else => return inner_node, | ||
| 5350 | } | 5365 | } |
| 5351 | 5366 | ||
| 5352 | // hack to get zig fmt to render a comma in builtin calls | 5367 | // 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, | ... | @@ -5354,7 +5369,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, |
| 5354 | 5369 | ||
| 5355 | const node_to_cast = try parseCExpr(c, it, source, source_loc, scope); | 5370 | const node_to_cast = try parseCExpr(c, it, source, source_loc, scope); |
| 5356 | 5371 | ||
| 5357 | if (it.next().?.id != .RParen) { | 5372 | if (saw_l_paren and it.next().?.id != .RParen) { |
| 5358 | const first_tok = it.list.at(0); | 5373 | const first_tok = it.list.at(0); |
| 5359 | try failDecl( | 5374 | try failDecl( |
| 5360 | c, | 5375 | c, |
test/translate_c.zig+3| ... | @@ -2538,10 +2538,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -2538,10 +2538,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2538 | 2538 | ||
| 2539 | cases.add("macro cast", | 2539 | cases.add("macro cast", |
| 2540 | \\#define FOO(bar) baz((void *)(baz)) | 2540 | \\#define FOO(bar) baz((void *)(baz)) |
| 2541 | \\#define BAR (void*) a | ||
| 2541 | , &[_][]const u8{ | 2542 | , &[_][]const u8{ |
| 2542 | \\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))) { | 2543 | \\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))) { |
| 2543 | \\ 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)); | 2544 | \\ 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)); |
| 2544 | \\} | 2545 | \\} |
| 2546 | , | ||
| 2547 | \\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); | ||
| 2545 | }); | 2548 | }); |
| 2546 | 2549 | ||
| 2547 | cases.add("macro conditional operator", | 2550 | cases.add("macro conditional operator", |