From abe7305e169be2047d65f96e6525d3828684f058 Mon Sep 17 00:00:00 2001 From: Vexu Date: Sat, 7 Mar 2020 17:36:17 +0200 Subject: [PATCH] translate-c remove redundant grouping, fix nested loops without blocks. --- src-self-hosted/translate_c.zig | 39 ++++++++++----------------------- test/translate_c.zig | 23 +++++++++++++++---- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index b13a0d4bf9..41e4665ffe 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -2237,6 +2237,7 @@ fn transWhileLoop( .id = .Loop, }; while_node.body = try transStmt(rp, &loop_scope, ZigClangWhileStmt_getBody(stmt), .unused, .r_value); + _ = try appendToken(rp.c, .Semicolon, ";"); return &while_node.base; } @@ -2346,8 +2347,10 @@ fn transForLoop( try block_scope.?.block_node.statements.push(&while_node.base); block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); return &block_scope.?.block_node.base; - } else + } else { + _ = try appendToken(rp.c, .Semicolon, ";"); return &while_node.base; + } } fn transSwitch( @@ -5576,14 +5579,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, ); return error.ParseError; } - // deref is often used together with casts so we group the lhs expression - const group = try c.a().create(ast.Node.GroupedExpression); - group.* = .{ - .lparen = try appendToken(c, .LParen, "("), - .expr = node, - .rparen = try appendToken(c, .RParen, ")"), - }; - const deref = try transCreateNodePtrDeref(c, &group.base); + const deref = try transCreateNodePtrDeref(c, node); node = try transCreateNodeFieldAccess(c, deref, source[name_tok.start..name_tok.end]); continue; }, @@ -5627,7 +5623,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, }, .Ampersand => { op_token = try appendToken(c, .Ampersand, "&"); - op_id .BitAnd; + op_id = .BitAnd; }, .Plus => { op_token = try appendToken(c, .Plus, "+"); @@ -5635,7 +5631,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, }, .Minus => { op_token = try appendToken(c, .Minus, "-"); - op_id .Sub; + op_id = .Sub; }, .AmpersandAmpersand => { op_token = try appendToken(c, .Keyword_and, "and"); @@ -5707,7 +5703,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, }, .BangEqual => { op_token = try appendToken(c, .BangEqual, "!="); - op_id = .BangEqual; + op_id = .BangEqual; }, .EqualEqual => { op_token = try appendToken(c, .EqualEqual, "=="); @@ -5760,25 +5756,12 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, return &node.base; }, .Asterisk => { - // deref is often used together with casts so we group the lhs expression - const group = try c.a().create(ast.Node.GroupedExpression); - group.* = .{ - .lparen = try appendToken(c, .LParen, "("), - .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope), - .rparen = try appendToken(c, .RParen, ")"), - }; - return try transCreateNodePtrDeref(c, &group.base); + const node = try parseCPrefixOpExpr(c, it, source, source_loc, scope); + return try transCreateNodePtrDeref(c, node); }, .Ampersand => { - // address of is often used together with casts so we group the rhs expression const node = try transCreateNodePrefixOp(c, .AddressOf, .Ampersand, "&"); - const group = try c.a().create(ast.Node.GroupedExpression); - group.* = .{ - .lparen = try appendToken(c, .LParen, "("), - .expr = try parseCPrefixOpExpr(c, it, source, source_loc, scope), - .rparen = try appendToken(c, .RParen, ")"), - }; - node.rhs = &group.base; + node.rhs = try parseCPrefixOpExpr(c, it, source, source_loc, scope); return &node.base; }, else => { diff --git a/test/translate_c.zig b/test/translate_c.zig index 01614ae9c9..d4ee871793 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -3,6 +3,22 @@ const std = @import("std"); const CrossTarget = std.zig.CrossTarget; pub fn addCases(cases: *tests.TranslateCContext) void { + cases.add("nested loops without blocks", + \\void foo() { + \\ while (0) while (0) {} + \\ for (;;) while (0); + \\ for (;;) do {} while (0); + \\} + , &[_][]const u8{ + \\pub export fn foo() void { + \\ while (@as(c_int, 0) != 0) while (@as(c_int, 0) != 0) {}; + \\ while (true) while (@as(c_int, 0) != 0) {}; + \\ while (true) while (true) { + \\ if (!(@as(c_int, 0) != 0)) break; + \\ }; + \\} + }); + cases.add("macro comma operator", \\#define foo (foo, bar) \\#define bar(x) (&x, +3, 4 == 4, 5 * 6, baz(1, 2), 2 % 2, baz(1,2)) @@ -14,7 +30,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , \\pub inline fn bar(x: var) @TypeOf(baz(1, 2)) { \\ return blk: { - \\ _ = &(x); + \\ _ = &x; \\ _ = 3; \\ _ = 4 == 4; \\ _ = 5 * 6; @@ -1993,7 +2009,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { , \\pub const DOT = a.b; , - \\pub const ARROW = (a).*.b; + \\pub const ARROW = a.*.b; }); cases.add("array access", @@ -2762,12 +2778,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} \\*_XPrivDisplay; \\typedef struct _XDisplay Display; - \\#define DefaultScreen(dpy) (((_XPrivDisplay)(dpy))->default_screen) + \\#define DefaultScreen(dpy) (((_XPrivDisplay)(dpy))->default_screen) \\ , &[_][]const u8{ \\pub inline fn DefaultScreen(dpy: var) @TypeOf((if (@typeInfo(@TypeOf(dpy)) == .Pointer) @ptrCast(_XPrivDisplay, @alignCast(@alignOf(_XPrivDisplay.Child), dpy)) else if (@typeInfo(@TypeOf(dpy)) == .Int) @intToPtr(_XPrivDisplay, dpy) else @as(_XPrivDisplay, dpy)).*.default_screen) { \\ return (if (@typeInfo(@TypeOf(dpy)) == .Pointer) @ptrCast(_XPrivDisplay, @alignCast(@alignOf(_XPrivDisplay.Child), dpy)) else if (@typeInfo(@TypeOf(dpy)) == .Int) @intToPtr(_XPrivDisplay, dpy) else @as(_XPrivDisplay, dpy)).*.default_screen; \\} }); - }