authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-29 23:38:00+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-30 19:45:08+01:00
logc944865fc7e66603bdb605c31ac70da323ecdbdc
tree3fa8964ecca3a2858c97d1fb5ca76d33da295348
parentcbd42e44d6321e59c7e89019e28bcf5299210795

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

2 files changed, 50 insertions(+), 6 deletions(-)

src-self-hosted/translate_c.zig+34-6
......@@ -1991,6 +1991,29 @@ fn transInitListExprRecord(
19911991 return &init_node.base;
19921992}
19931993
1994fn 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
19942017fn 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
3881fn transCreateNodeContainerInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {
3909fn 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+16
......@@ -3,6 +3,22 @@ const tests = @import("tests.zig");
33const nl = std.cstr.line_sep;
44
55pub 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);