authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-20 00:10:25+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-20 00:12:08+02:00
logd172a7335c5b943102e2c9e70c1bbdfa20eec955
tree7980681946a7d82bd79a2ba075b5009f0e7d96b8
parentb7f18164f96f7e695d295c12c06fddf25803b08b
signature Commit is signed but in an unrecognized format.

translate-c-2 copy parametrs to stack


4 files changed, 227 insertions(+), 169 deletions(-)

lib/std/zig/ast.zig+4-4
......@@ -1456,8 +1456,8 @@ pub const Node = struct {
14561456 LessThan,
14571457 MergeErrorSets,
14581458 Mod,
1459 Mult,
1460 MultWrap,
1459 Mul,
1460 MulWrap,
14611461 Period,
14621462 Range,
14631463 Sub,
......@@ -1514,8 +1514,8 @@ pub const Node = struct {
15141514 Op.LessThan,
15151515 Op.MergeErrorSets,
15161516 Op.Mod,
1517 Op.Mult,
1518 Op.MultWrap,
1517 Op.Mul,
1518 Op.MulWrap,
15191519 Op.Period,
15201520 Op.Range,
15211521 Op.Sub,
lib/std/zig/parse.zig+2-2
......@@ -2120,11 +2120,11 @@ fn parseMultiplyOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
21202120 const token = nextToken(it);
21212121 const op = switch (token.ptr.id) {
21222122 .PipePipe => ops{ .BoolOr = {} },
2123 .Asterisk => ops{ .Mult = {} },
2123 .Asterisk => ops{ .Mul = {} },
21242124 .Slash => ops{ .Div = {} },
21252125 .Percent => ops{ .Mod = {} },
21262126 .AsteriskAsterisk => ops{ .ArrayMult = {} },
2127 .AsteriskPercent => ops{ .MultWrap = {} },
2127 .AsteriskPercent => ops{ .MulWrap = {} },
21282128 else => {
21292129 putBackToken(it, token.index);
21302130 return null;
src-self-hosted/translate_c.zig+61-69
......@@ -49,7 +49,6 @@ const Scope = struct {
4949 Block,
5050 Root,
5151 Condition,
52 FnDef,
5352 Loop,
5453 };
5554
......@@ -121,39 +120,6 @@ const Scope = struct {
121120 }
122121 };
123122
124 const FnDef = struct {
125 base: Scope,
126 params: AliasList,
127
128 fn init(c: *Context) FnDef {
129 return .{
130 .base = .{
131 .id = .FnDef,
132 .parent = &c.global_scope.base,
133 },
134 .params = AliasList.init(c.a()),
135 };
136 }
137
138 fn getAlias(scope: *FnDef, name: []const u8) ?[]const u8 {
139 var it = scope.params.iterator(0);
140 while (it.next()) |p| {
141 if (mem.eql(u8, p.name, name))
142 return p.alias;
143 }
144 return scope.base.parent.?.getAlias(name);
145 }
146
147 fn contains(scope: *FnDef, name: []const u8) bool {
148 var it = scope.params.iterator(0);
149 while (it.next()) |p| {
150 if (mem.eql(u8, p.name, name))
151 return true;
152 }
153 return scope.base.parent.?.contains(name);
154 }
155 };
156
157123 fn findBlockScope(inner: *Scope, c: *Context) !*Scope.Block {
158124 var scope = inner;
159125 while (true) {
......@@ -179,7 +145,6 @@ const Scope = struct {
179145 fn getAlias(scope: *Scope, name: []const u8) ?[]const u8 {
180146 return switch (scope.id) {
181147 .Root => null,
182 .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),
183148 .Block => @fieldParentPtr(Block, "base", scope).getAlias(name),
184149 .Switch, .Loop, .Condition => scope.parent.?.getAlias(name),
185150 };
......@@ -188,7 +153,6 @@ const Scope = struct {
188153 fn contains(scope: *Scope, name: []const u8) bool {
189154 return switch (scope.id) {
190155 .Root => @fieldParentPtr(Root, "base", scope).contains(name),
191 .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),
192156 .Block => @fieldParentPtr(Block, "base", scope).contains(name),
193157 .Switch, .Loop, .Condition => scope.parent.?.contains(name),
194158 };
......@@ -198,7 +162,7 @@ const Scope = struct {
198162 var scope = inner;
199163 while (true) {
200164 switch (scope.id) {
201 .FnDef => unreachable,
165 .Root => unreachable,
202166 .Switch => return scope,
203167 .Loop => return scope,
204168 else => scope = scope.parent.?,
......@@ -210,7 +174,7 @@ const Scope = struct {
210174 var scope = inner;
211175 while (true) {
212176 switch (scope.id) {
213 .FnDef => unreachable,
177 .Root => unreachable,
214178 .Switch => return @fieldParentPtr(Switch, "base", scope),
215179 else => scope = scope.parent.?,
216180 }
......@@ -382,17 +346,12 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
382346 const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl)));
383347 _ = try c.decl_table.put(@ptrToInt(fn_decl), fn_name);
384348 const fn_decl_loc = ZigClangFunctionDecl_getLocation(fn_decl);
385 const fn_qt = ZigClangFunctionDecl_getType(fn_decl);
386 const fn_type = ZigClangQualType_getTypePtr(fn_qt);
387 var fndef_scope = Scope.FnDef.init(c);
388 var scope = &fndef_scope.base;
389349 const has_body = ZigClangFunctionDecl_hasBody(fn_decl);
390350 const storage_class = ZigClangFunctionDecl_getStorageClass(fn_decl);
391351 const decl_ctx = FnDeclContext{
392352 .fn_name = fn_name,
393353 .has_body = has_body,
394354 .storage_class = storage_class,
395 .scope = &scope,
396355 .is_export = switch (storage_class) {
397356 .None => has_body,
398357 .Extern, .Static => false,
......@@ -402,6 +361,15 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
402361 else => unreachable,
403362 },
404363 };
364
365 var fn_qt = ZigClangFunctionDecl_getType(fn_decl);
366 var fn_type = ZigClangQualType_getTypePtr(fn_qt);
367 if (ZigClangType_getTypeClass(fn_type) == .Attributed) {
368 const attr_type = @ptrCast(*const ZigClangAttributedType, fn_type);
369 fn_qt = ZigClangAttributedType_getEquivalentType(attr_type);
370 fn_type = ZigClangQualType_getTypePtr(fn_qt);
371 }
372
405373 const proto_node = switch (ZigClangType_getTypeClass(fn_type)) {
406374 .FunctionProto => blk: {
407375 const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type);
......@@ -431,15 +399,39 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
431399
432400 // actual function definition with body
433401 const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);
434 const body_node = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) {
402 const block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null);
403 var scope = &block_scope.base;
404 const block_node = try transCreateNodeBlock(rp.c, null);
405 block_scope.block_node = block_node;
406
407 var it = proto_node.params.iterator(0);
408 while (it.next()) |p| {
409 const param = @fieldParentPtr(ast.Node.ParamDecl, "base", p.*);
410 const param_name = tokenSlice(c, param.name_token.?);
411
412 const checked_param_name = if (try scope.createAlias(rp.c, param_name)) |a| blk: {
413 try block_scope.variables.push(.{ .name = param_name, .alias = a });
414 break :blk a;
415 } else param_name;
416 const arg_name = try std.fmt.allocPrint(c.a(), "_arg_{}", .{checked_param_name});
417
418 const node = try transCreateNodeVarDecl(c, false, false, checked_param_name);
419 node.eq_token = try appendToken(c, .Equal, "=");
420 node.init_node = try transCreateNodeIdentifier(c, arg_name);
421 node.semicolon_token = try appendToken(c, .Semicolon, ";");
422 try block_node.statements.push(&node.base);
423 param.name_token = try appendIdentifier(c, arg_name);
424 _ = try appendToken(c, .Colon, ":");
425 }
426
427 transCompoundStmtInline(rp, &block_scope.base, @ptrCast(*const ZigClangCompoundStmt, body_stmt), block_node) catch |err| switch (err) {
435428 error.OutOfMemory => |e| return e,
436429 error.UnsupportedTranslation,
437430 error.UnsupportedType,
438431 => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),
439432 };
440 assert(body_node.id == .Block);
441 proto_node.body_node = body_node;
442
433 block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
434 proto_node.body_node = &block_node.base;
443435 return addTopLevelDecl(c, fn_name, &proto_node.base);
444436}
445437
......@@ -614,7 +606,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
614606 const name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name });
615607 _ = try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), name);
616608
617 const node = try transCreateNodeVarDecl(c, true, true, name);
609 const node = try transCreateNodeVarDecl(c, !is_unnamed, true, name);
618610
619611 node.eq_token = try appendToken(c, .Equal, "=");
620612
......@@ -1020,10 +1012,10 @@ fn transBinaryOperator(
10201012 .Mul => {
10211013 if (cIsUnsignedInteger(qt)) {
10221014 op_token = try appendToken(rp.c, .AsteriskPercent, "*%");
1023 op_id = .MultWrap;
1015 op_id = .MulWrap;
10241016 } else {
10251017 op_token = try appendToken(rp.c, .Asterisk, "*");
1026 op_id = .Mult;
1018 op_id = .Mul;
10271019 }
10281020 },
10291021 .Div => {
......@@ -1287,8 +1279,16 @@ fn transBoolExpr(
12871279 undefined;
12881280 var res = try transExpr(rp, scope, expr, used, lrvalue);
12891281
1290 if (isBoolRes(res))
1282 if (isBoolRes(res)) {
1283 if (!grouped and res.id == .GroupedExpression) {
1284 const group = @fieldParentPtr(ast.Node.GroupedExpression, "base", res);
1285 res = group.expr;
1286 // get zig fmt to work properly
1287 tokenSlice(rp.c, group.lparen)[0] = ')';
1288 }
12911289 return res;
1290 }
1291
12921292 const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr));
12931293 const node = try finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used);
12941294
......@@ -2399,9 +2399,9 @@ fn transCreatePostCrement(
23992399fn transCompoundAssignOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundAssignOperator, used: ResultUsed) TransError!*ast.Node {
24002400 switch (ZigClangCompoundAssignOperator_getOpcode(stmt)) {
24012401 .MulAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))
2402 return transCreateCompoundAssign(rp, scope, stmt, .AssignMulWrap, .AsteriskPercentEqual, "*%=", .MultWrap, .AsteriskPercent, "*%", used)
2402 return transCreateCompoundAssign(rp, scope, stmt, .AssignMulWrap, .AsteriskPercentEqual, "*%=", .MulWrap, .AsteriskPercent, "*%", used)
24032403 else
2404 return transCreateCompoundAssign(rp, scope, stmt, .AssignMul, .AsteriskEqual, "*=", .Mult, .Asterisk, "*", used),
2404 return transCreateCompoundAssign(rp, scope, stmt, .AssignMul, .AsteriskEqual, "*=", .Mul, .Asterisk, "*", used),
24052405 .AddAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))
24062406 return transCreateCompoundAssign(rp, scope, stmt, .AssignAddWrap, .PlusPercentEqual, "+%=", .AddWrap, .PlusPercent, "+%", used)
24072407 else
......@@ -3688,7 +3688,6 @@ const FnDeclContext = struct {
36883688 fn_name: []const u8,
36893689 has_body: bool,
36903690 storage_class: ZigClangStorageClass,
3691 scope: **Scope,
36923691 is_export: bool,
36933692};
36943693
......@@ -3754,9 +3753,6 @@ fn finishTransFnProto(
37543753 // TODO check for always_inline attribute
37553754 // TODO check for align attribute
37563755
3757 var fndef_scope = Scope.FnDef.init(rp.c);
3758 const scope = &fndef_scope.base;
3759
37603756 // pub extern fn name(...) T
37613757 const pub_tok = if (is_pub) try appendToken(rp.c, .Keyword_pub, "pub") else null;
37623758 const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null;
......@@ -3782,15 +3778,11 @@ fn finishTransFnProto(
37823778 const param_name_tok: ?ast.TokenIndex = blk: {
37833779 if (fn_decl != null) {
37843780 const param = ZigClangFunctionDecl_getParamDecl(fn_decl.?, @intCast(c_uint, i));
3785 var param_name: []const u8 = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param)));
3781 const param_name: []const u8 = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, param)));
37863782 if (param_name.len < 1)
3787 param_name = try std.fmt.allocPrint(rp.c.a(), "arg_{}", .{rp.c.getMangle()});
3788 const checked_param_name = if (try scope.createAlias(rp.c, param_name)) |a| blk: {
3789 try fndef_scope.params.push(.{ .name = param_name, .alias = a });
3790 break :blk a;
3791 } else param_name;
3783 break :blk null;
37923784
3793 const result = try appendIdentifier(rp.c, checked_param_name);
3785 const result = try appendIdentifier(rp.c, param_name);
37943786 _ = try appendToken(rp.c, .Colon, ":");
37953787 break :blk result;
37963788 }
......@@ -4124,8 +4116,8 @@ fn transMacroDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8,
41244116
41254117fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
41264118 const rp = makeRestorePoint(c);
4127 var fndef_scope = Scope.FnDef.init(c);
4128 const scope = &fndef_scope.base;
4119 const block_scope = try Scope.Block.init(c, &c.global_scope.base, null);
4120 const scope = &block_scope.base;
41294121
41304122 const pub_tok = try appendToken(c, .Keyword_pub, "pub");
41314123 const inline_tok = try appendToken(c, .Keyword_inline, "inline");
......@@ -4143,7 +4135,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u
41434135 return error.ParseError;
41444136
41454137 const checked_name = if (try scope.createAlias(c, param_tok.bytes)) |alias| blk: {
4146 try fndef_scope.params.push(.{ .name = param_tok.bytes, .alias = alias });
4138 try block_scope.variables.push(.{ .name = param_tok.bytes, .alias = alias });
41474139 break :blk alias;
41484140 } else param_tok.bytes;
41494141
......@@ -4521,9 +4513,9 @@ fn parseCPrefixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
45214513 }
45224514}
45234515
4524fn tokenSlice(c: *Context, token: ast.TokenIndex) []const u8 {
4516fn tokenSlice(c: *Context, token: ast.TokenIndex) []u8 {
45254517 const tok = c.tree.tokens.at(token);
4526 return c.source_buffer.toSliceConst()[tok.start..tok.end];
4518 return c.source_buffer.toSlice()[tok.start..tok.end];
45274519}
45284520
45294521fn getContainer(c: *Context, node: *ast.Node) ?*ast.Node {
test/translate_c.zig+160-94
......@@ -127,16 +127,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
127127 });
128128
129129 cases.addC_both("add, sub, mul, div, rem",
130 \\int s(int a, int b) {
131 \\ int c;
130 \\int s() {
131 \\ int a, b, c;
132132 \\ c = a + b;
133133 \\ c = a - b;
134134 \\ c = a * b;
135135 \\ c = a / b;
136136 \\ c = a % b;
137137 \\}
138 \\unsigned u(unsigned a, unsigned b) {
139 \\ unsigned c;
138 \\unsigned u() {
139 \\ unsigned a, b, c;
140140 \\ c = a + b;
141141 \\ c = a - b;
142142 \\ c = a * b;
......@@ -144,7 +144,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
144144 \\ c = a % b;
145145 \\}
146146 , &[_][]const u8{
147 \\pub export fn s(a: c_int, b: c_int) c_int {
147 \\pub export fn s() c_int {
148 \\ var a: c_int = undefined;
149 \\ var b: c_int = undefined;
148150 \\ var c: c_int = undefined;
149151 \\ c = (a + b);
150152 \\ c = (a - b);
......@@ -152,7 +154,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
152154 \\ c = @divTrunc(a, b);
153155 \\ c = @rem(a, b);
154156 \\}
155 \\pub export fn u(a: c_uint, b: c_uint) c_uint {
157 \\pub export fn u() c_uint {
158 \\ var a: c_uint = undefined;
159 \\ var b: c_uint = undefined;
156160 \\ var c: c_uint = undefined;
157161 \\ c = (a +% b);
158162 \\ c = (a -% b);
......@@ -544,21 +548,25 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
544548 });
545549
546550 cases.addC_both("void cast",
547 \\void foo(int a) {
551 \\void foo() {
552 \\ int a;
548553 \\ (void) a;
549554 \\}
550555 , &[_][]const u8{
551 \\pub export fn foo(a: c_int) void {
556 \\pub export fn foo() void {
557 \\ var a: c_int = undefined;
552558 \\ _ = a;
553559 \\}
554560 });
555561
556562 cases.addC_both("implicit cast to void *",
557 \\void *foo(unsigned short *x) {
563 \\void *foo() {
564 \\ unsigned short *x;
558565 \\ return x;
559566 \\}
560567 , &[_][]const u8{
561 \\pub export fn foo(x: [*c]c_ushort) ?*c_void {
568 \\pub export fn foo() ?*c_void {
569 \\ var x: [*c]c_ushort = undefined;
562570 \\ return @ptrCast(?*c_void, x);
563571 \\}
564572 });
......@@ -659,11 +667,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
659667 });
660668
661669 cases.addC_both("pointer casting",
662 \\float *ptrcast(int *a) {
670 \\float *ptrcast() {
671 \\ int *a;
663672 \\ return (float *)a;
664673 \\}
665674 , &[_][]const u8{
666 \\pub export fn ptrcast(a: [*c]c_int) [*c]f32 {
675 \\pub export fn ptrcast() [*c]f32 {
676 \\ var a: [*c]c_int = undefined;
667677 \\ return @ptrCast([*c]f32, @alignCast(@alignOf(f32), a));
668678 \\}
669679 });
......@@ -702,29 +712,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
702712 \\}
703713 });
704714
705 cases.addC_both("function call",
706 \\static void bar(void) { }
707 \\void foo(int *(baz)(void)) {
708 \\ bar();
709 \\ baz();
710 \\}
711 , &[_][]const u8{
712 \\pub fn bar() void {}
713 \\pub export fn foo(baz: ?extern fn () [*c]c_int) void {
714 \\ bar();
715 \\ _ = baz.?();
716 \\}
717 });
718
719715 cases.addC_both("while on non-bool",
720 \\int while_none_bool(int a, float b, void *c) {
716 \\int while_none_bool() {
717 \\ int a;
718 \\ float b;
719 \\ void *c;
721720 \\ while (a) return 0;
722721 \\ while (b) return 1;
723722 \\ while (c) return 2;
724723 \\ return 3;
725724 \\}
726725 , &[_][]const u8{
727 \\pub export fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
726 \\pub export fn while_none_bool() c_int {
727 \\ var a: c_int = undefined;
728 \\ var b: f32 = undefined;
729 \\ var c: ?*c_void = undefined;
728730 \\ while (a != 0) return 0;
729731 \\ while (b != 0) return 1;
730732 \\ while (c != null) return 2;
......@@ -733,14 +735,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
733735 });
734736
735737 cases.addC_both("for on non-bool",
736 \\int for_none_bool(int a, float b, void *c) {
738 \\int for_none_bool() {
739 \\ int a;
740 \\ float b;
741 \\ void *c;
737742 \\ for (;a;) return 0;
738743 \\ for (;b;) return 1;
739744 \\ for (;c;) return 2;
740745 \\ return 3;
741746 \\}
742747 , &[_][]const u8{
743 \\pub export fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
748 \\pub export fn for_none_bool() c_int {
749 \\ var a: c_int = undefined;
750 \\ var b: f32 = undefined;
751 \\ var c: ?*c_void = undefined;
744752 \\ while (a != 0) return 0;
745753 \\ while (b != 0) return 1;
746754 \\ while (c != null) return 2;
......@@ -770,11 +778,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
770778 });
771779
772780 cases.addC_both("normal deref",
773 \\void foo(int *x) {
781 \\void foo() {
782 \\ int *x;
774783 \\ *x = 1;
775784 \\}
776785 , &[_][]const u8{
777 \\pub export fn foo(x: [*c]c_int) void {
786 \\pub export fn foo() void {
787 \\ var x: [*c]c_int = undefined;
778788 \\ x.?.* = 1;
779789 \\}
780790 });
......@@ -794,24 +804,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
794804 });
795805
796806 cases.addC_both("bin not",
797 \\int foo(int x) {
807 \\int foo() {
808 \\ int x;
798809 \\ return ~x;
799810 \\}
800811 , &[_][]const u8{
801 \\pub export fn foo(x: c_int) c_int {
812 \\pub export fn foo() c_int {
813 \\ var x: c_int = undefined;
802814 \\ return ~x;
803815 \\}
804816 });
805817
806818 cases.addC_both("bool not",
807 \\int foo(int a, float b, void *c) {
819 \\int foo() {
820 \\ int a;
821 \\ float b;
822 \\ void *c;
808823 \\ return !(a == 0);
809824 \\ return !a;
810825 \\ return !b;
811826 \\ return !c;
812827 \\}
813828 , &[_][]const u8{
814 \\pub export fn foo(a: c_int, b: f32, c: ?*c_void) c_int {
829 \\pub export fn foo() c_int {
830 \\ var a: c_int = undefined;
831 \\ var b: f32 = undefined;
832 \\ var c: ?*c_void = undefined;
815833 \\ return !(a == 0);
816834 \\ return !(a != 0);
817835 \\ return !(b != 0);
......@@ -829,6 +847,15 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
829847 \\}
830848 });
831849
850 if (builtin.os != builtin.Os.windows) {
851 // sysv_abi not currently supported on windows
852 cases.add_both("Macro qualified functions",
853 \\void __attribute__((sysv_abi)) foo(void);
854 , &[_][]const u8{
855 \\pub extern fn foo() void;
856 });
857 }
858
832859 /////////////// Cases that pass for only stage2 ////////////////
833860
834861 cases.add_2("Parameterless function prototypes",
......@@ -1027,7 +1054,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
10271054 \\pub const GLbitfield = c_uint;
10281055 \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void;
10291056 \\pub const OpenGLProc = ?extern fn () void;
1030 \\pub const struct_unnamed_1 = extern struct {
1057 \\const struct_unnamed_1 = extern struct {
10311058 \\ Clear: PFNGLCLEARPROC,
10321059 \\};
10331060 \\pub const union_OpenGLProcs = extern union {
......@@ -1088,7 +1115,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
10881115 \\pub var a: c_long = @as(c_long, 2);
10891116 \\pub var b: c_long = @as(c_long, 2);
10901117 \\pub var c: c_int = 4;
1091 \\pub export fn foo(c_1: u8) void {
1118 \\pub export fn foo(_arg_c_1: u8) void {
1119 \\ var c_1 = _arg_c_1;
10921120 \\ var a_2: c_int = undefined;
10931121 \\ var b_3: u8 = @as(u8, 123);
10941122 \\ b_3 = @as(u8, a_2);
......@@ -1105,7 +1133,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
11051133 \\ return 2, 4, 6;
11061134 \\}
11071135 , &[_][]const u8{
1108 \\pub export fn foo(c: u8) c_int {
1136 \\pub export fn foo(_arg_c: u8) c_int {
1137 \\ var c = _arg_c;
11091138 \\ _ = 2;
11101139 \\ _ = 4;
11111140 \\ _ = 2;
......@@ -1121,7 +1150,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
11211150 \\ a = b = 2;
11221151 \\}
11231152 , &[_][]const u8{
1124 \\pub export fn foo(c: u8) c_int {
1153 \\pub export fn foo(_arg_c: u8) c_int {
1154 \\ var c = _arg_c;
11251155 \\ var a: c_int = undefined;
11261156 \\ var b: c_int = undefined;
11271157 \\ a = blk: {
......@@ -1142,7 +1172,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
11421172 \\ }
11431173 \\}
11441174 , &[_][]const u8{
1145 \\pub export fn foo(c: u8) c_int {
1175 \\pub export fn foo(_arg_c: u8) c_int {
1176 \\ var c = _arg_c;
11461177 \\ if (2 != 0) {
11471178 \\ var a: c_int = 2;
11481179 \\ }
......@@ -1265,7 +1296,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
12651296 \\ }
12661297 \\}
12671298 , &[_][]const u8{
1268 \\pub export fn switch_fn(i: c_int) c_int {
1299 \\pub export fn switch_fn(_arg_i: c_int) c_int {
1300 \\ var i = _arg_i;
12691301 \\ var res: c_int = 0;
12701302 \\ __switch: {
12711303 \\ __case_2: {
......@@ -1316,7 +1348,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13161348 cases.add_2("restrict -> noalias",
13171349 \\void foo(void *restrict bar, void *restrict);
13181350 , &[_][]const u8{
1319 \\pub extern fn foo(noalias bar: ?*c_void, noalias arg_1: ?*c_void) void;
1351 \\pub extern fn foo(noalias bar: ?*c_void, noalias ?*c_void) void;
13201352 });
13211353
13221354 cases.add_2("assign",
......@@ -1326,7 +1358,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13261358 \\ a = tmp;
13271359 \\}
13281360 , &[_][]const u8{
1329 \\pub export fn max(a: c_int) c_int {
1361 \\pub export fn max(_arg_a: c_int) c_int {
1362 \\ var a = _arg_a;
13301363 \\ var tmp: c_int = undefined;
13311364 \\ tmp = a;
13321365 \\ a = tmp;
......@@ -1339,7 +1372,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13391372 \\ c = b = a;
13401373 \\}
13411374 , &[_][]const u8{
1342 \\pub export fn max(a: c_int) void {
1375 \\pub export fn max(_arg_a: c_int) void {
1376 \\ var a = _arg_a;
13431377 \\ var b: c_int = undefined;
13441378 \\ var c: c_int = undefined;
13451379 \\ c = blk: {
......@@ -1369,7 +1403,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13691403 \\ return (int)a;
13701404 \\}
13711405 , &[_][]const u8{
1372 \\pub export fn float_to_int(a: f32) c_int {
1406 \\pub export fn float_to_int(_arg_a: f32) c_int {
1407 \\ var a = _arg_a;
13731408 \\ return @floatToInt(c_int, a);
13741409 \\}
13751410 });
......@@ -1434,19 +1469,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14341469 \\}
14351470 });
14361471
1437 cases.add_2("shift right with a fixed size type, no while", // TODO can fold this into "shift right assign with a fixed size type" once `>>=` is handled in translate-c-2
1438 \\#include <stdint.h>
1439 \\uint32_t some_func(uint32_t a) {
1440 \\ uint32_t b = a >> 1;
1441 \\ return b;
1442 \\}
1443 , &[_][]const u8{
1444 \\pub export fn some_func(a: u32) u32 {
1445 \\ var b: u32 = a >> @as(u5, 1);
1446 \\ return b;
1447 \\}
1448 });
1449
14501472 cases.add_2("logical and, logical or, on non-bool values, extra parens",
14511473 \\enum Foo {
14521474 \\ FooA,
......@@ -1480,7 +1502,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14801502 \\ C,
14811503 \\};
14821504 \\pub const SomeTypedef = c_int;
1483 \\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int {
1505 \\pub export fn and_or_non_bool(_arg_a: c_int, _arg_b: f32, _arg_c: ?*c_void) c_int {
1506 \\ var a = _arg_a;
1507 \\ var b = _arg_b;
1508 \\ var c = _arg_c;
14841509 \\ var d: enum_Foo = @as(enum_Foo, FooA);
14851510 \\ var e: c_int = @boolToInt(((a != 0) and (b != 0)));
14861511 \\ var f: c_int = @boolToInt(((b != 0) and (c != null)));
......@@ -1532,12 +1557,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15321557 \\ return (a & b) ^ (a | b);
15331558 \\}
15341559 , &[_][]const u8{
1535 \\pub export fn max(a: c_int, b: c_int) c_int {
1560 \\pub export fn max(_arg_a: c_int, _arg_b: c_int) c_int {
1561 \\ var a = _arg_a;
1562 \\ var b = _arg_b;
15361563 \\ return ((a & b) ^ (a | b));
15371564 \\}
15381565 });
15391566
1540 cases.add_2("comparison operators (no if)", // TODO Come up with less contrived tests? Make sure to cover all these comparisons. Can use `if` after it is added to translate-c-2
1567 cases.add_2("comparison operators (no if)", // TODO Come up with less contrived tests? Make sure to cover all these comparisons.
15411568 \\int test_comparisons(int a, int b) {
15421569 \\ int c = (a < b);
15431570 \\ int d = (a > b);
......@@ -1549,7 +1576,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15491576 \\ return i;
15501577 \\}
15511578 , &[_][]const u8{
1552 \\pub export fn test_comparisons(a: c_int, b: c_int) c_int {
1579 \\pub export fn test_comparisons(_arg_a: c_int, _arg_b: c_int) c_int {
1580 \\ var a = _arg_a;
1581 \\ var b = _arg_b;
15531582 \\ var c: c_int = @boolToInt((a < b));
15541583 \\ var d: c_int = @boolToInt((a > b));
15551584 \\ var e: c_int = @boolToInt((a <= b));
......@@ -1570,9 +1599,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15701599 \\ return a;
15711600 \\}
15721601 , &[_][]const u8{
1573 \\pub export fn max(a: c_int, b: c_int) c_int {
1574 \\ if ((a == b)) return a;
1575 \\ if ((a != b)) return b;
1602 \\pub export fn max(_arg_a: c_int, _arg_b: c_int) c_int {
1603 \\ var a = _arg_a;
1604 \\ var b = _arg_b;
1605 \\ if (a == b) return a;
1606 \\ if (a != b) return b;
15761607 \\ return a;
15771608 \\}
15781609 });
......@@ -1646,7 +1677,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
16461677 \\}
16471678 , &[_][]const u8{
16481679 \\pub export var array: [100]c_int = .{0} ** 100;
1649 \\pub export fn foo(index: c_int) c_int {
1680 \\pub export fn foo(_arg_index: c_int) c_int {
1681 \\ var index = _arg_index;
16501682 \\ return array[index];
16511683 \\}
16521684 ,
......@@ -1670,9 +1702,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
16701702 \\ return a;
16711703 \\}
16721704 , &[_][]const u8{
1673 \\pub export fn max(a: c_int, b: c_int) c_int {
1674 \\ if (((a < b) or (a == b))) return b;
1675 \\ if (((a >= b) and (a == b))) return a;
1705 \\pub export fn max(_arg_a: c_int, _arg_b: c_int) c_int {
1706 \\ var a = _arg_a;
1707 \\ var b = _arg_b;
1708 \\ if ((a < b) or (a == b)) return b;
1709 \\ if ((a >= b) and (a == b)) return a;
16761710 \\ return a;
16771711 \\}
16781712 });
......@@ -1690,10 +1724,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
16901724 \\ if (a < b) ; else ;
16911725 \\}
16921726 , &[_][]const u8{
1693 \\pub export fn max(a: c_int, b: c_int) c_int {
1694 \\ if ((a < b)) return b;
1695 \\ if ((a < b)) return b else return a;
1696 \\ if ((a < b)) {} else {}
1727 \\pub export fn max(_arg_a: c_int, _arg_b: c_int) c_int {
1728 \\ var a = _arg_a;
1729 \\ var b = _arg_b;
1730 \\ if (a < b) return b;
1731 \\ if (a < b) return b else return a;
1732 \\ if (a < b) {} else {}
16971733 \\}
16981734 });
16991735
......@@ -1715,7 +1751,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17151751 \\ B,
17161752 \\ C,
17171753 \\};
1718 \\pub export fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
1754 \\pub export fn if_none_bool(_arg_a: c_int, _arg_b: f32, _arg_c: ?*c_void, _arg_d: enum_SomeEnum) c_int {
1755 \\ var a = _arg_a;
1756 \\ var b = _arg_b;
1757 \\ var c = _arg_c;
1758 \\ var d = _arg_d;
17191759 \\ if (a != 0) return 0;
17201760 \\ if (b != 0) return 1;
17211761 \\ if (c != null) return 2;
......@@ -1741,8 +1781,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17411781 \\ return a < 0 ? -a : a;
17421782 \\}
17431783 , &[_][]const u8{
1744 \\pub export fn abs(a: c_int) c_int {
1745 \\ return if ((a < 0)) -a else a;
1784 \\pub export fn abs(_arg_a: c_int) c_int {
1785 \\ var a = _arg_a;
1786 \\ return if (a < 0) -a else a;
17461787 \\}
17471788 });
17481789
......@@ -1756,11 +1797,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17561797 \\ return a;
17571798 \\}
17581799 , &[_][]const u8{
1759 \\pub export fn foo1(a: c_uint) c_uint {
1800 \\pub export fn foo1(_arg_a: c_uint) c_uint {
1801 \\ var a = _arg_a;
17601802 \\ a +%= 1;
17611803 \\ return a;
17621804 \\}
1763 \\pub export fn foo2(a: c_int) c_int {
1805 \\pub export fn foo2(_arg_a: c_int) c_int {
1806 \\ var a = _arg_a;
17641807 \\ a += 1;
17651808 \\ return a;
17661809 \\}
......@@ -1848,10 +1891,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
18481891 \\ }
18491892 \\ return i;
18501893 \\}
1851 , &[_][]const u8{// TODO function arguments should be copied
1852 \\pub export fn log2(a: c_uint) c_int {
1894 , &[_][]const u8{
1895 \\pub export fn log2(_arg_a: c_uint) c_int {
1896 \\ var a = _arg_a;
18531897 \\ var i: c_int = 0;
1854 \\ while ((a > @as(c_uint, 0))) {
1898 \\ while (a > @as(c_uint, 0)) {
18551899 \\ a >>= @as(@import("std").math.Log2Int(c_int), 1);
18561900 \\ }
18571901 \\ return i;
......@@ -1868,9 +1912,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
18681912 \\ return i;
18691913 \\}
18701914 , &[_][]const u8{
1871 \\pub export fn log2(a: u32) c_int {
1915 \\pub export fn log2(_arg_a: u32) c_int {
1916 \\ var a = _arg_a;
18721917 \\ var i: c_int = 0;
1873 \\ while ((a > @as(c_uint, 0))) {
1918 \\ while (a > @as(c_uint, 0)) {
18741919 \\ a >>= @as(@import("std").math.Log2Int(c_int), 1);
18751920 \\ }
18761921 \\ return i;
......@@ -2076,7 +2121,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
20762121 \\pub extern fn fn_char(x: u8) void;
20772122 \\pub extern fn fn_bool(x: bool) void;
20782123 \\pub extern fn fn_ptr(x: ?*c_void) void;
2079 \\pub export fn call(q: c_int) void {
2124 \\pub export fn call(_arg_q: c_int) void {
2125 \\ var q = _arg_q;
20802126 \\ fn_int(@floatToInt(c_int, 3));
20812127 \\ fn_int(@floatToInt(c_int, 3));
20822128 \\ fn_int(@floatToInt(c_int, 3));
......@@ -2096,6 +2142,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
20962142 \\}
20972143 });
20982144
2145 cases.add_2("function call",
2146 \\static void bar(void) { }
2147 \\void foo(int *(baz)(void)) {
2148 \\ bar();
2149 \\ baz();
2150 \\}
2151 , &[_][]const u8{
2152 \\pub fn bar() void {}
2153 \\pub export fn foo(_arg_baz: ?extern fn () [*c]c_int) void {
2154 \\ var baz = _arg_baz;
2155 \\ bar();
2156 \\ _ = baz.?();
2157 \\}
2158 });
2159
20992160 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
21002161
21012162 cases.add("macro defines string literal with hex",
......@@ -2122,15 +2183,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
21222183 \\pub const FOO_CHAR = 63;
21232184 });
21242185
2125 if (builtin.os != builtin.Os.windows) {
2126 // sysv_abi not currently supported on windows
2127 cases.add("Macro qualified functions",
2128 \\void __attribute__((sysv_abi)) foo(void);
2129 , &[_][]const u8{
2130 \\pub extern fn foo() void;
2131 });
2132 }
2133
21342186 /////////////// Cases for only stage1 because stage2 behavior is better ////////////////
21352187 cases.addC("Parameterless function prototypes",
21362188 \\void foo() {}
......@@ -3045,4 +3097,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
30453097 \\ fn_ptr(@intToPtr(?*c_void, 42));
30463098 \\}
30473099 });
3100
3101 cases.addC("function call",
3102 \\static void bar(void) { }
3103 \\void foo(int *(baz)(void)) {
3104 \\ bar();
3105 \\ baz();
3106 \\}
3107 , &[_][]const u8{
3108 \\pub fn bar() void {}
3109 \\pub export fn foo(baz: ?extern fn () [*c]c_int) void {
3110 \\ bar();
3111 \\ _ = baz.?();
3112 \\}
3113 });
30483114}