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(...@@ -1991,6 +1991,29 @@ fn transInitListExprRecord(
1991 return &init_node.base;1991 return &init_node.base;
1992}1992}
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
1994fn transInitListExprArray(2017fn transInitListExprArray(
1995 rp: RestorePoint,2018 rp: RestorePoint,
1996 scope: *Scope,2019 scope: *Scope,
...@@ -2011,8 +2034,13 @@ fn transInitListExprArray(...@@ -2011,8 +2034,13 @@ fn transInitListExprArray(
2011 var init_node: *ast.Node.SuffixOp = undefined;2034 var init_node: *ast.Node.SuffixOp = undefined;
2012 var cat_tok: ast.TokenIndex = undefined;2035 var cat_tok: ast.TokenIndex = undefined;
2013 if (init_count != 0) {2036 if (init_count != 0) {
2014 const dot_tok = try appendToken(rp.c, .Period, ".");2037 const ty_node = try transCreateNodeArrayType(
2015 init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);2038 rp,
2039 loc,
2040 ZigClangQualType_getTypePtr(child_qt),
2041 init_count,
2042 );
2043 init_node = try transCreateNodeArrayInitializer(rp.c, ty_node);
2016 var i: c_uint = 0;2044 var i: c_uint = 0;
2017 while (i < init_count) : (i += 1) {2045 while (i < init_count) : (i += 1) {
2018 const elem_expr = ZigClangInitListExpr_getInit(expr, i);2046 const elem_expr = ZigClangInitListExpr_getInit(expr, i);
...@@ -2026,8 +2054,8 @@ fn transInitListExprArray(...@@ -2026,8 +2054,8 @@ fn transInitListExprArray(
2026 cat_tok = try appendToken(rp.c, .PlusPlus, "++");2054 cat_tok = try appendToken(rp.c, .PlusPlus, "++");
2027 }2055 }
20282056
2029 const dot_tok = try appendToken(rp.c, .Period, ".");2057 const ty_node = try transCreateNodeArrayType(rp, loc, ZigClangQualType_getTypePtr(child_qt), 1);
2030 var filler_init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);2058 var filler_init_node = try transCreateNodeArrayInitializer(rp.c, ty_node);
2031 const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);2059 const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
2032 try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value));2060 try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value));
2033 filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");2061 filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
...@@ -3878,11 +3906,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {...@@ -3878,11 +3906,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
3878 return &node.base;3906 return &node.base;
3879}3907}
38803908
3881fn transCreateNodeContainerInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {3909fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp {
3882 _ = try appendToken(c, .LBrace, "{");3910 _ = try appendToken(c, .LBrace, "{");
3883 const node = try c.a().create(ast.Node.SuffixOp);3911 const node = try c.a().create(ast.Node.SuffixOp);
3884 node.* = ast.Node.SuffixOp{3912 node.* = ast.Node.SuffixOp{
3885 .lhs = .{ .dot = dot_tok },3913 .lhs = .{ .node = ty },
3886 .op = .{3914 .op = .{
3887 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),3915 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
3888 },3916 },
test/run_translated_c.zig+16
...@@ -3,6 +3,22 @@ const tests = @import("tests.zig");...@@ -3,6 +3,22 @@ const tests = @import("tests.zig");
3const nl = std.cstr.line_sep;3const nl = std.cstr.line_sep;
44
5pub fn addCases(cases: *tests.RunTranslatedCContext) void {5pub 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
6 cases.add("forward declarations",22 cases.add("forward declarations",
7 \\#include <stdlib.h>23 \\#include <stdlib.h>
8 \\int foo(int);24 \\int foo(int);