diff options
| author | LemonBoy <thatlemon@gmail.com> | 2020-01-29 23:38:00 +0100 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2020-01-30 19:45:08 +0100 |
| commit | c944865fc7e66603bdb605c31ac70da323ecdbdc (patch) | |
| tree | 3fa8964ecca3a2858c97d1fb5ca76d33da295348 | |
| parent | cbd42e44d6321e59c7e89019e28bcf5299210795 (diff) | |
| download | zig-c944865fc7e66603bdb605c31ac70da323ecdbdc.tar.gz zig-c944865fc7e66603bdb605c31ac70da323ecdbdc.zip | |
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
| -rw-r--r-- | src-self-hosted/translate_c.zig | 40 | ||||
| -rw-r--r-- | test/run_translated_c.zig | 16 |
2 files changed, 50 insertions, 6 deletions
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index d4df998774..0c186b40f4 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -1991,6 +1991,29 @@ fn transInitListExprRecord( return &init_node.base; } +fn transCreateNodeArrayType( + rp: RestorePoint, + source_loc: ZigClangSourceLocation, + ty: *const ZigClangType, + len: var, +) TransError!*ast.Node { + var node = try transCreateNodePrefixOp( + rp.c, + .{ + .ArrayType = .{ + .len_expr = undefined, + .sentinel = null, + }, + }, + .LBracket, + "[", + ); + node.op.ArrayType.len_expr = try transCreateNodeInt(rp.c, len); + _ = try appendToken(rp.c, .RBracket, "]"); + node.rhs = try transType(rp, ty, source_loc); + return &node.base; +} + fn transInitListExprArray( rp: RestorePoint, scope: *Scope, @@ -2011,8 +2034,13 @@ fn transInitListExprArray( var init_node: *ast.Node.SuffixOp = undefined; var cat_tok: ast.TokenIndex = undefined; if (init_count != 0) { - const dot_tok = try appendToken(rp.c, .Period, "."); - init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok); + const ty_node = try transCreateNodeArrayType( + rp, + loc, + ZigClangQualType_getTypePtr(child_qt), + init_count, + ); + init_node = try transCreateNodeArrayInitializer(rp.c, ty_node); var i: c_uint = 0; while (i < init_count) : (i += 1) { const elem_expr = ZigClangInitListExpr_getInit(expr, i); @@ -2026,8 +2054,8 @@ fn transInitListExprArray( cat_tok = try appendToken(rp.c, .PlusPlus, "++"); } - const dot_tok = try appendToken(rp.c, .Period, "."); - var filler_init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok); + const ty_node = try transCreateNodeArrayType(rp, loc, ZigClangQualType_getTypePtr(child_qt), 1); + var filler_init_node = try transCreateNodeArrayInitializer(rp.c, ty_node); const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr); try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value)); filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); @@ -3878,11 +3906,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node { return &node.base; } -fn transCreateNodeContainerInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp { +fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp { _ = try appendToken(c, .LBrace, "{"); const node = try c.a().create(ast.Node.SuffixOp); node.* = ast.Node.SuffixOp{ - .lhs = .{ .dot = dot_tok }, + .lhs = .{ .node = ty }, .op = .{ .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()), }, diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index d48c3dc5c0..629a850836 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -3,6 +3,22 @@ const tests = @import("tests.zig"); const nl = std.cstr.line_sep; pub fn addCases(cases: *tests.RunTranslatedCContext) void { + cases.add("array initializer", + \\#include <stdlib.h> + \\int main(int argc, char **argv) { + \\ int a0[4] = {1}; + \\ int a1[4] = {1,2,3,4}; + \\ int s0 = 0, s1 = 0; + \\ for (int i = 0; i < 4; i++) { + \\ s0 += a0[i]; + \\ s1 += a1[i]; + \\ } + \\ if (s0 != 1) abort(); + \\ if (s1 != 10) abort(); + \\ return 0; + \\} + , ""); + cases.add("forward declarations", \\#include <stdlib.h> \\int foo(int); |
