Skip to content

Commit eb9608b

Browse files
committed
Generate compilable code for array inits
The compiler still doesn't like too much the newfangled anonymous arrays so let's use the old-style declarations. Closes #4181
1 parent d448c3d commit eb9608b

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

src-self-hosted/translate_c.zig

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,29 @@ fn transInitListExprRecord(
19911991
return &init_node.base;
19921992
}
19931993

1994+
fn transCreateNodeArrayType(
1995+
rp: RestorePoint,
1996+
source_loc: ZigClangSourceLocation,
1997+
ty: *const ZigClangType,
1998+
len: var,
1999+
) TransError!*ast.Node {
2000+
var node = try transCreateNodePrefixOp(
2001+
rp.c,
2002+
.{
2003+
.ArrayType = .{
2004+
.len_expr = undefined,
2005+
.sentinel = null,
2006+
},
2007+
},
2008+
.LBracket,
2009+
"[",
2010+
);
2011+
node.op.ArrayType.len_expr = try transCreateNodeInt(rp.c, len);
2012+
_ = try appendToken(rp.c, .RBracket, "]");
2013+
node.rhs = try transType(rp, ty, source_loc);
2014+
return &node.base;
2015+
}
2016+
19942017
fn transInitListExprArray(
19952018
rp: RestorePoint,
19962019
scope: *Scope,
@@ -2011,8 +2034,13 @@ fn transInitListExprArray(
20112034
var init_node: *ast.Node.SuffixOp = undefined;
20122035
var cat_tok: ast.TokenIndex = undefined;
20132036
if (init_count != 0) {
2014-
const dot_tok = try appendToken(rp.c, .Period, ".");
2015-
init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);
2037+
const ty_node = try transCreateNodeArrayType(
2038+
rp,
2039+
loc,
2040+
ZigClangQualType_getTypePtr(child_qt),
2041+
init_count,
2042+
);
2043+
init_node = try transCreateNodeArrayInitializer(rp.c, ty_node);
20162044
var i: c_uint = 0;
20172045
while (i < init_count) : (i += 1) {
20182046
const elem_expr = ZigClangInitListExpr_getInit(expr, i);
@@ -2026,8 +2054,8 @@ fn transInitListExprArray(
20262054
cat_tok = try appendToken(rp.c, .PlusPlus, "++");
20272055
}
20282056

2029-
const dot_tok = try appendToken(rp.c, .Period, ".");
2030-
var filler_init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);
2057+
const ty_node = try transCreateNodeArrayType(rp, loc, ZigClangQualType_getTypePtr(child_qt), 1);
2058+
var filler_init_node = try transCreateNodeArrayInitializer(rp.c, ty_node);
20312059
const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
20322060
try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value));
20332061
filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
@@ -3878,11 +3906,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
38783906
return &node.base;
38793907
}
38803908

3881-
fn transCreateNodeContainerInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {
3909+
fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp {
38823910
_ = try appendToken(c, .LBrace, "{");
38833911
const node = try c.a().create(ast.Node.SuffixOp);
38843912
node.* = ast.Node.SuffixOp{
3885-
.lhs = .{ .dot = dot_tok },
3913+
.lhs = .{ .node = ty },
38863914
.op = .{
38873915
.ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
38883916
},

test/run_translated_c.zig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@ const tests = @import("tests.zig");
33
const nl = std.cstr.line_sep;
44

55
pub fn addCases(cases: *tests.RunTranslatedCContext) void {
6+
cases.add("array initializer",
7+
\\#include <stdlib.h>
8+
\\int main(int argc, char **argv) {
9+
\\ int a0[4] = {1};
10+
\\ int a1[4] = {1,2,3,4};
11+
\\ int s0 = 0, s1 = 0;
12+
\\ for (int i = 0; i < 4; i++) {
13+
\\ s0 += a0[i];
14+
\\ s1 += a1[i];
15+
\\ }
16+
\\ if (s0 != 1) abort();
17+
\\ if (s1 != 10) abort();
18+
\\ return 0;
19+
\\}
20+
, "");
21+
622
cases.add("forward declarations",
723
\\#include <stdlib.h>
824
\\int foo(int);

0 commit comments

Comments
 (0)