Skip to content

Commit 3fbe4f5

Browse files
committed
translate-c: get all translate-c tests passing
1 parent 3984c6d commit 3fbe4f5

File tree

3 files changed

+281
-233
lines changed

3 files changed

+281
-233
lines changed

src/translate_c.zig

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
622622
return; // Avoid processing this decl twice
623623

624624
const is_pub = mangled_name == null;
625-
const is_thread_local = var_decl.getTLSKind() != .None;
625+
const is_threadlocal = var_decl.getTLSKind() != .None;
626626
const scope = &c.global_scope.base;
627627

628628
// TODO https://github.com/ziglang/zig/issues/3756
@@ -706,6 +706,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
706706
.is_const = is_const,
707707
.is_extern = is_extern,
708708
.is_export = is_export,
709+
.is_threadlocal = is_threadlocal,
709710
.linksection_string = linksection_string,
710711
.alignment = alignment,
711712
.name = checked_name,
@@ -1307,6 +1308,7 @@ fn transDeclStmtOne(
13071308
.is_const = is_const,
13081309
.is_extern = false,
13091310
.is_export = false,
1311+
.is_threadlocal = false,
13101312
.linksection_string = null,
13111313
.alignment = null,
13121314
.name = mangled_name,
@@ -2886,11 +2888,11 @@ fn transCreateCompoundAssign(
28862888
if ((is_mod or is_div) and is_signed) {
28872889
const rhs_node = try transExpr(c, &block_scope.base, rhs, .used);
28882890
const builtin = if (is_mod)
2889-
try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node })
2891+
try Tag.rem.create(c.arena, .{ .lhs = ref_node, .rhs = rhs_node })
28902892
else
2891-
try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
2893+
try Tag.div_trunc.create(c.arena, .{ .lhs = ref_node, .rhs = rhs_node });
28922894

2893-
const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, lhs_node, builtin, .used);
2895+
const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, ref_node, builtin, .used);
28942896
try block_scope.statements.append(assign);
28952897
} else {
28962898
var rhs_node = try transExpr(c, &block_scope.base, rhs, .used);
@@ -4794,6 +4796,10 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
47944796
.LBracket => {
47954797
const index = try macroBoolToInt(c, try parseCExpr(c, m, scope));
47964798
node = try Tag.array_access.create(c.arena, .{ .lhs = node, .rhs = index });
4799+
if (m.next().? != .RBracket) {
4800+
try m.fail(c, "unable to translate C expr: expected ']'", .{});
4801+
return error.ParseError;
4802+
}
47974803
},
47984804
.LParen => {
47994805
var args = std.ArrayList(Node).init(c.gpa);

src/translate_c/ast.zig

Lines changed: 62 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ pub const Payload = struct {
458458
is_const: bool,
459459
is_extern: bool,
460460
is_export: bool,
461+
is_threadlocal: bool,
461462
alignment: ?c_uint,
462463
linksection_string: ?[]const u8,
463464
name: []const u8,
@@ -1164,42 +1165,42 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
11641165
},
11651166
});
11661167
},
1167-
.add => return renderBinOp(c, node, .add, .plus, "+"),
1168+
.add => return renderBinOpGrouped(c, node, .add, .plus, "+"),
11681169
.add_assign => return renderBinOp(c, node, .assign_add, .plus_equal, "+="),
1169-
.add_wrap => return renderBinOp(c, node, .add_wrap, .plus_percent, "+%"),
1170+
.add_wrap => return renderBinOpGrouped(c, node, .add_wrap, .plus_percent, "+%"),
11701171
.add_wrap_assign => return renderBinOp(c, node, .assign_add_wrap, .plus_percent_equal, "+%="),
1171-
.sub => return renderBinOp(c, node, .sub, .minus, "-"),
1172+
.sub => return renderBinOpGrouped(c, node, .sub, .minus, "-"),
11721173
.sub_assign => return renderBinOp(c, node, .assign_sub, .minus_equal, "-="),
1173-
.sub_wrap => return renderBinOp(c, node, .sub_wrap, .minus_percent, "-%"),
1174+
.sub_wrap => return renderBinOpGrouped(c, node, .sub_wrap, .minus_percent, "-%"),
11741175
.sub_wrap_assign => return renderBinOp(c, node, .assign_sub_wrap, .minus_percent_equal, "-%="),
1175-
.mul => return renderBinOp(c, node, .mul, .asterisk, "*"),
1176+
.mul => return renderBinOpGrouped(c, node, .mul, .asterisk, "*"),
11761177
.mul_assign => return renderBinOp(c, node, .assign_mul, .asterisk_equal, "*="),
1177-
.mul_wrap => return renderBinOp(c, node, .mul_wrap, .asterisk_percent, "*="),
1178+
.mul_wrap => return renderBinOpGrouped(c, node, .mul_wrap, .asterisk_percent, "*%"),
11781179
.mul_wrap_assign => return renderBinOp(c, node, .assign_mul_wrap, .asterisk_percent_equal, "*%="),
1179-
.div => return renderBinOp(c, node, .div, .slash, "/"),
1180+
.div => return renderBinOpGrouped(c, node, .div, .slash, "/"),
11801181
.div_assign => return renderBinOp(c, node, .assign_div, .slash_equal, "/="),
1181-
.shl => return renderBinOp(c, node, .bit_shift_left, .angle_bracket_angle_bracket_left, "<<"),
1182+
.shl => return renderBinOpGrouped(c, node, .bit_shift_left, .angle_bracket_angle_bracket_left, "<<"),
11821183
.shl_assign => return renderBinOp(c, node, .assign_bit_shift_left, .angle_bracket_angle_bracket_left_equal, "<<="),
1183-
.shr => return renderBinOp(c, node, .bit_shift_right, .angle_bracket_angle_bracket_right, ">>"),
1184+
.shr => return renderBinOpGrouped(c, node, .bit_shift_right, .angle_bracket_angle_bracket_right, ">>"),
11841185
.shr_assign => return renderBinOp(c, node, .assign_bit_shift_right, .angle_bracket_angle_bracket_right_equal, ">>="),
1185-
.mod => return renderBinOp(c, node, .mod, .percent, "%"),
1186+
.mod => return renderBinOpGrouped(c, node, .mod, .percent, "%"),
11861187
.mod_assign => return renderBinOp(c, node, .assign_mod, .percent_equal, "%="),
1187-
.@"and" => return renderBinOp(c, node, .bool_and, .keyword_and, "and"),
1188-
.@"or" => return renderBinOp(c, node, .bool_or, .keyword_or, "or"),
1189-
.less_than => return renderBinOp(c, node, .less_than, .angle_bracket_left, "<"),
1190-
.less_than_equal => return renderBinOp(c, node, .less_or_equal, .angle_bracket_left_equal, "<="),
1191-
.greater_than => return renderBinOp(c, node, .greater_than, .angle_bracket_right, ">="),
1192-
.greater_than_equal => return renderBinOp(c, node, .greater_or_equal, .angle_bracket_right_equal, ">="),
1193-
.equal => return renderBinOp(c, node, .equal_equal, .equal_equal, "=="),
1194-
.not_equal => return renderBinOp(c, node, .bang_equal, .bang_equal, "!="),
1195-
.bit_and => return renderBinOp(c, node, .bit_and, .ampersand, "&"),
1188+
.@"and" => return renderBinOpGrouped(c, node, .bool_and, .keyword_and, "and"),
1189+
.@"or" => return renderBinOpGrouped(c, node, .bool_or, .keyword_or, "or"),
1190+
.less_than => return renderBinOpGrouped(c, node, .less_than, .angle_bracket_left, "<"),
1191+
.less_than_equal => return renderBinOpGrouped(c, node, .less_or_equal, .angle_bracket_left_equal, "<="),
1192+
.greater_than => return renderBinOpGrouped(c, node, .greater_than, .angle_bracket_right, ">="),
1193+
.greater_than_equal => return renderBinOpGrouped(c, node, .greater_or_equal, .angle_bracket_right_equal, ">="),
1194+
.equal => return renderBinOpGrouped(c, node, .equal_equal, .equal_equal, "=="),
1195+
.not_equal => return renderBinOpGrouped(c, node, .bang_equal, .bang_equal, "!="),
1196+
.bit_and => return renderBinOpGrouped(c, node, .bit_and, .ampersand, "&"),
11961197
.bit_and_assign => return renderBinOp(c, node, .assign_bit_and, .ampersand_equal, "&="),
1197-
.bit_or => return renderBinOp(c, node, .bit_or, .pipe, "|"),
1198+
.bit_or => return renderBinOpGrouped(c, node, .bit_or, .pipe, "|"),
11981199
.bit_or_assign => return renderBinOp(c, node, .assign_bit_or, .pipe_equal, "|="),
1199-
.bit_xor => return renderBinOp(c, node, .bit_xor, .caret, "^"),
1200+
.bit_xor => return renderBinOpGrouped(c, node, .bit_xor, .caret, "^"),
12001201
.bit_xor_assign => return renderBinOp(c, node, .assign_bit_xor, .caret_equal, "^="),
12011202
.array_cat => return renderBinOp(c, node, .array_cat, .plus_plus, "++"),
1202-
.ellipsis3 => return renderBinOp(c, node, .switch_range, .ellipsis3, "..."),
1203+
.ellipsis3 => return renderBinOpGrouped(c, node, .switch_range, .ellipsis3, "..."),
12031204
.assign => return renderBinOp(c, node, .assign, .equal, "="),
12041205
.empty_block => {
12051206
const l_brace = try c.addToken(.l_brace, "{");
@@ -1222,7 +1223,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
12221223

12231224
_ = try c.addToken(.r_brace, "}");
12241225
return c.addNode(.{
1225-
.tag = .block_two,
1226+
.tag = .block_two_semicolon,
12261227
.main_token = l_brace,
12271228
.data = .{
12281229
.lhs = stmt,
@@ -1410,13 +1411,13 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
14101411
var cases = try c.gpa.alloc(NodeIndex, payload.cases.len);
14111412
defer c.gpa.free(cases);
14121413
for (payload.cases) |case, i| {
1413-
if (i != 0) _ = try c.addToken(.comma, ",");
14141414
cases[i] = try renderNode(c, case);
1415+
_ = try c.addToken(.comma, ",");
14151416
}
14161417
const span = try c.listToSpan(cases);
14171418
_ = try c.addToken(.r_brace, "}");
14181419
return c.addNode(.{
1419-
.tag = .@"switch",
1420+
.tag = .switch_comma,
14201421
.main_token = switch_tok,
14211422
.data = .{
14221423
.lhs = cond,
@@ -1623,9 +1624,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
16231624
const payload = node.castTag(.tuple).?.data;
16241625
_ = try c.addToken(.period, ".");
16251626
const l_brace = try c.addToken(.l_brace, "{");
1626-
var inits = try c.gpa.alloc(NodeIndex, std.math.max(payload.len, 1));
1627+
var inits = try c.gpa.alloc(NodeIndex, std.math.max(payload.len, 2));
16271628
defer c.gpa.free(inits);
16281629
inits[0] = 0;
1630+
inits[1] = 0;
16291631
for (payload) |init, i| {
16301632
if (i != 0) _ = try c.addToken(.comma, ",");
16311633
inits[i] = try renderNode(c, init);
@@ -1661,17 +1663,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
16611663
defer c.gpa.free(inits);
16621664
inits[0] = 0;
16631665
for (payload.inits) |init, i| {
1664-
if (i != 0) _ = try c.addToken(.comma, ",");
16651666
_ = try c.addToken(.period, ".");
16661667
_ = try c.addIdentifier(init.name);
16671668
_ = try c.addToken(.equal, "=");
16681669
inits[i] = try renderNode(c, init.value);
1670+
_ = try c.addToken(.comma, ",");
16691671
}
16701672
_ = try c.addToken(.r_brace, "}");
16711673

16721674
if (payload.inits.len < 2) {
16731675
return c.addNode(.{
1674-
.tag = .struct_init_one,
1676+
.tag = .struct_init_one_comma,
16751677
.main_token = l_brace,
16761678
.data = .{
16771679
.lhs = lhs,
@@ -1681,7 +1683,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
16811683
} else {
16821684
const span = try c.listToSpan(inits);
16831685
return c.addNode(.{
1684-
.tag = .struct_init,
1686+
.tag = .struct_init_comma,
16851687
.main_token = l_brace,
16861688
.data = .{
16871689
.lhs = lhs,
@@ -1791,13 +1793,13 @@ fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex
17911793
defer c.gpa.free(rendered);
17921794
rendered[0] = 0;
17931795
for (inits) |init, i| {
1794-
if (i != 0) _ = try c.addToken(.comma, ",");
17951796
rendered[i] = try renderNode(c, init);
1797+
_ = try c.addToken(.comma, ",");
17961798
}
17971799
_ = try c.addToken(.r_brace, "}");
17981800
if (inits.len < 2) {
17991801
return c.addNode(.{
1800-
.tag = .array_init_one,
1802+
.tag = .array_init_one_comma,
18011803
.main_token = l_brace,
18021804
.data = .{
18031805
.lhs = lhs,
@@ -1807,7 +1809,7 @@ fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex
18071809
} else {
18081810
const span = try c.listToSpan(rendered);
18091811
return c.addNode(.{
1810-
.tag = .array_init,
1812+
.tag = .array_init_comma,
18111813
.main_token = l_brace,
18121814
.data = .{
18131815
.lhs = lhs,
@@ -1842,25 +1844,32 @@ fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
18421844
fn addSemicolonIfNeeded(c: *Context, node: Node) !void {
18431845
switch (node.tag()) {
18441846
.warning => unreachable,
1845-
.var_decl, .var_simple, .arg_redecl, .alias, .enum_redecl, .block, .empty_block, .@"switch" => {},
1847+
.var_decl, .var_simple, .arg_redecl, .alias, .enum_redecl, .block, .empty_block, .block_single, .@"switch" => {},
18461848
.while_true => {
18471849
const payload = node.castTag(.while_true).?.data;
1848-
return addSemicolonIfNeeded(c, payload);
1850+
return addSemicolonIfNotBlock(c, payload);
18491851
},
18501852
.@"while" => {
18511853
const payload = node.castTag(.@"while").?.data;
1852-
return addSemicolonIfNeeded(c, payload.body);
1854+
return addSemicolonIfNotBlock(c, payload.body);
18531855
},
18541856
.@"if" => {
18551857
const payload = node.castTag(.@"if").?.data;
18561858
if (payload.@"else") |some|
1857-
return addSemicolonIfNeeded(c, some);
1858-
return addSemicolonIfNeeded(c, payload.then);
1859+
return addSemicolonIfNotBlock(c, some);
1860+
return addSemicolonIfNotBlock(c, payload.then);
18591861
},
18601862
else => _ = try c.addToken(.semicolon, ";"),
18611863
}
18621864
}
18631865

1866+
fn addSemicolonIfNotBlock(c: *Context, node: Node) !void {
1867+
switch (node.tag()) {
1868+
.block, .empty_block, .block_single, => {},
1869+
else => _ = try c.addToken(.semicolon, ";"),
1870+
}
1871+
}
1872+
18641873
fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
18651874
switch (node.tag()) {
18661875
.null_literal,
@@ -1918,6 +1927,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
19181927
.func,
19191928
.call,
19201929
.array_type,
1930+
.bool_to_int,
19211931
=> {
19221932
// no grouping needed
19231933
return renderNode(c, node);
@@ -1926,7 +1936,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
19261936
.opaque_literal,
19271937
.empty_array,
19281938
.block_single,
1929-
.bool_to_int,
19301939
.add,
19311940
.add_wrap,
19321941
.sub,
@@ -2022,7 +2031,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: T
20222031
});
20232032
}
20242033

2025-
fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2034+
fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
20262035
const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
20272036
const lhs = try renderNodeGrouped(c, payload.lhs);
20282037
return c.addNode(.{
@@ -2035,6 +2044,19 @@ fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: Toke
20352044
});
20362045
}
20372046

2047+
fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
2048+
const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
2049+
const lhs = try renderNode(c, payload.lhs);
2050+
return c.addNode(.{
2051+
.tag = tag,
2052+
.main_token = try c.addToken(tok_tag, bytes),
2053+
.data = .{
2054+
.lhs = lhs,
2055+
.rhs = try renderNode(c, payload.rhs),
2056+
},
2057+
});
2058+
}
2059+
20382060
fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {
20392061
const import_tok = try c.addToken(.builtin, "@import");
20402062
_ = try c.addToken(.l_paren, "(");
@@ -2143,6 +2165,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
21432165
if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
21442166
if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
21452167
if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
2168+
if (payload.is_threadlocal) _ = try c.addToken(.keyword_threadlocal, "threadlocal");
21462169
const mut_tok = if (payload.is_const)
21472170
try c.addToken(.keyword_const, "const")
21482171
else

0 commit comments

Comments
 (0)