authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-15 16:07:21+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:40:43+02:00
log78fba4e0213dc9bcc2274ef6c31023256a235301
tree9e790ca729367a6b2a89c4568ad8ffc4e82e64ea
parent77a11e6873d0f30950d8a523c990d32b5a25a658
signature Commit is signed but in an unrecognized format.

translate-c: get all run-translated-c tests passing


4 files changed, 120 insertions(+), 132 deletions(-)

lib/std/zig/parser_test.zig+6-6
...@@ -3669,12 +3669,12 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {...@@ -3669,12 +3669,12 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {
3669 );3669 );
3670}3670}
36713671
3672//test "zig fmt: C var args" {3672test "zig fmt: C var args" {
3673// try testCanonical(3673 try testCanonical(
3674// \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;3674 \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
3675// \\3675 \\
3676// );3676 );
3677//}3677}
36783678
3679//test "zig fmt: Only indent multiline string literals in function calls" {3679//test "zig fmt: Only indent multiline string literals in function calls" {
3680// try testCanonical(3680// try testCanonical(
lib/std/zig/render.zig+1-1
...@@ -1308,7 +1308,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S...@@ -1308,7 +1308,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S
1308 .r_paren => break,1308 .r_paren => break,
1309 .comma => {1309 .comma => {
1310 try renderToken(ais, tree, last_param_token, .space); // ,1310 try renderToken(ais, tree, last_param_token, .space); // ,
1311 last_param_token += 1;1311 continue;
1312 },1312 },
1313 else => {}, // Parameter type without a name.1313 else => {}, // Parameter type without a name.
1314 }1314 }
src/translate_c.zig+30-13
...@@ -990,7 +990,10 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node {...@@ -990,7 +990,10 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node {
990 }));990 }));
991 }991 }
992992
993 break :blk try Tag.@"enum".create(c.arena, try c.arena.dupe(ast.Payload.Enum.Field, fields.items));993 break :blk try Tag.@"enum".create(c.arena, .{
994 .int_type = init_arg_expr,
995 .fields = try c.arena.dupe(ast.Payload.Enum.Field, fields.items),
996 });
994 } else blk: {997 } else blk: {
995 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {});998 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {});
996 break :blk Tag.opaque_literal.init();999 break :blk Tag.opaque_literal.init();
...@@ -1540,8 +1543,8 @@ fn finishBoolExpr(...@@ -1540,8 +1543,8 @@ fn finishBoolExpr(
1540 }1543 }
1541 },1544 },
1542 .Pointer => {1545 .Pointer => {
1543 // node == null1546 // node != null
1544 return Tag.equal.create(c.arena, .{ .lhs = node, .rhs = Tag.null_literal.init() });1547 return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.null_literal.init() });
1545 },1548 },
1546 .Typedef => {1549 .Typedef => {
1547 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);1550 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
...@@ -1675,7 +1678,8 @@ fn transStringLiteralAsArray(...@@ -1675,7 +1678,8 @@ fn transStringLiteralAsArray(
1675 const ty = expr_base.getType().getTypePtr();1678 const ty = expr_base.getType().getTypePtr();
1676 const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty);1679 const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty);
16771680
1678 const arr_type = try transQualType(c, const_arr_ty.getElementType(), expr_base.getBeginLoc());1681 const elem_type = try transQualType(c, const_arr_ty.getElementType(), expr_base.getBeginLoc());
1682 const arr_type = try Tag.array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_type });
1679 const init_list = try c.arena.alloc(Node, array_size);1683 const init_list = try c.arena.alloc(Node, array_size);
16801684
1681 var i: c_uint = 0;1685 var i: c_uint = 0;
...@@ -2668,7 +2672,7 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat...@@ -2668,7 +2672,7 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat
2668 return Tag.bit_not.create(c.arena, try transExpr(c, scope, op_expr, .used));2672 return Tag.bit_not.create(c.arena, try transExpr(c, scope, op_expr, .used));
2669 },2673 },
2670 .LNot => {2674 .LNot => {
2671 return Tag.not.create(c.arena, try transExpr(c, scope, op_expr, .used));2675 return Tag.not.create(c.arena, try transBoolExpr(c, scope, op_expr, .used));
2672 },2676 },
2673 .Extension => {2677 .Extension => {
2674 return transExpr(c, scope, stmt.getSubExpr(), used);2678 return transExpr(c, scope, stmt.getSubExpr(), used);
...@@ -2969,8 +2973,15 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node {...@@ -2969,8 +2973,15 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node {
29692973
2970fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {2974fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {
2971 // TODO use something more accurate2975 // TODO use something more accurate
2972 const dbl = stmt.getValueAsApproximateDouble();2976 var dbl = stmt.getValueAsApproximateDouble();
2973 const node = try transCreateNodeNumber(c, dbl, .float);2977 const is_negative = dbl < 0;
2978 if (is_negative) dbl = -dbl;
2979 const str = try std.fmt.allocPrint(c.arena, "{d}", .{dbl});
2980 var node = if (dbl == std.math.floor(dbl))
2981 try Tag.integer_literal.create(c.arena, str)
2982 else
2983 try Tag.float_literal.create(c.arena, str);
2984 if (is_negative) node = try Tag.negate.create(c.arena, node);
2974 return maybeSuppressResult(c, scope, used, node);2985 return maybeSuppressResult(c, scope, used, node);
2975}2986}
29762987
...@@ -3004,8 +3015,11 @@ fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang...@@ -3004,8 +3015,11 @@ fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang
3004 },3015 },
3005 };3016 };
3006 defer cond_scope.deinit();3017 defer cond_scope.deinit();
3007 const cond_node = try transBoolExpr(c, &cond_scope.base, cond_expr, .used);3018
3008 var then_body = try Tag.identifier.create(c.arena, mangled_name);3019 const cond_ident = try Tag.identifier.create(c.arena, mangled_name);
3020 const ty = getExprQualType(c, cond_expr).getTypePtr();
3021 const cond_node = try finishBoolExpr(c, &cond_scope.base, cond_expr.getBeginLoc(), ty, cond_ident, .used);
3022 var then_body = cond_ident;
3009 if (!res_is_bool and isBoolRes(init_node)) {3023 if (!res_is_bool and isBoolRes(init_node)) {
3010 then_body = try Tag.bool_to_int.create(c.arena, then_body);3024 then_body = try Tag.bool_to_int.create(c.arena, then_body);
3011 }3025 }
...@@ -3489,11 +3503,13 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {...@@ -3489,11 +3503,13 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {
3489 else => @compileError("unimplemented"),3503 else => @compileError("unimplemented"),
3490 }3504 }
34913505
3492 const big: math.big.int.Const = .{ .limbs = limbs, .positive = !is_negative };3506 const big: math.big.int.Const = .{ .limbs = limbs, .positive = true };
3493 const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {3507 const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {
3494 error.OutOfMemory => return error.OutOfMemory,3508 error.OutOfMemory => return error.OutOfMemory,
3495 };3509 };
3496 return Tag.integer_literal.create(c.arena, str);3510 const res = try Tag.integer_literal.create(c.arena, str);
3511 if (is_negative) return Tag.negate.create(c.arena, res);
3512 return res;
3497}3513}
34983514
3499fn transCreateNodeNumber(c: *Context, num: anytype, num_kind: enum { int, float }) !Node {3515fn transCreateNodeNumber(c: *Context, num: anytype, num_kind: enum { int, float }) !Node {
...@@ -3567,7 +3583,7 @@ fn transCreateNodeShiftOp(...@@ -3567,7 +3583,7 @@ fn transCreateNodeShiftOp(
35673583
3568 const rhs_type = try qualTypeToLog2IntRef(c, stmt.getType(), rhs_location);3584 const rhs_type = try qualTypeToLog2IntRef(c, stmt.getType(), rhs_location);
3569 const rhs = try transExprCoercing(c, scope, rhs_expr, .used);3585 const rhs = try transExprCoercing(c, scope, rhs_expr, .used);
3570 const rhs_casted = try Tag.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs_type });3586 const rhs_casted = try Tag.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs });
35713587
3572 return transCreateNodeInfixOp(c, scope, op, lhs, rhs_casted, used);3588 return transCreateNodeInfixOp(c, scope, op, lhs, rhs_casted, used);
3573}3589}
...@@ -3622,7 +3638,8 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio...@@ -3622,7 +3638,8 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
3622 const is_volatile = child_qt.isVolatileQualified();3638 const is_volatile = child_qt.isVolatileQualified();
3623 const elem_type = try transQualType(c, child_qt, source_loc);3639 const elem_type = try transQualType(c, child_qt, source_loc);
3624 if (typeIsOpaque(c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(c, child_qt)) {3640 if (typeIsOpaque(c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(c, child_qt)) {
3625 return Tag.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });3641 const ptr = try Tag.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
3642 return Tag.optional_type.create(c.arena, ptr);
3626 }3643 }
36273644
3628 return Tag.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });3645 return Tag.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
src/translate_c/ast.zig+83-112
...@@ -491,7 +491,10 @@ pub const Payload = struct {...@@ -491,7 +491,10 @@ pub const Payload = struct {
491491
492 pub const Enum = struct {492 pub const Enum = struct {
493 base: Payload,493 base: Payload,
494 data: []Field,494 data: struct {
495 int_type: Node,
496 fields: []Field,
497 },
495498
496 pub const Field = struct {499 pub const Field = struct {
497 name: []const u8,500 name: []const u8,
...@@ -825,11 +828,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -825,11 +828,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
825 .main_token = try c.addToken(.identifier, "void"),828 .main_token = try c.addToken(.identifier, "void"),
826 .data = undefined,829 .data = undefined,
827 }),830 }),
828 .@"anytype" => return c.addNode(.{
829 .tag = .@"anytype",
830 .main_token = try c.addToken(.keyword_anytype, "anytype"),
831 .data = undefined,
832 }),
833 .noreturn_type => return c.addNode(.{831 .noreturn_type => return c.addNode(.{
834 .tag = .identifier,832 .tag = .identifier,
835 .main_token = try c.addToken(.identifier, "noreturn"),833 .main_token = try c.addToken(.identifier, "noreturn"),
...@@ -946,7 +944,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -946,7 +944,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
946 const payload = node.castTag(.char_literal).?.data;944 const payload = node.castTag(.char_literal).?.data;
947 return c.addNode(.{945 return c.addNode(.{
948 .tag = .identifier,946 .tag = .identifier,
949 .main_token = try c.addToken(.string_literal, payload),947 .main_token = try c.addToken(.char_literal, payload),
950 .data = undefined,948 .data = undefined,
951 });949 });
952 },950 },
...@@ -1268,7 +1266,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1268,7 +1266,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1268 const lhs = try c.addNode(.{1266 const lhs = try c.addNode(.{
1269 .tag = .identifier,1267 .tag = .identifier,
1270 .main_token = try c.addToken(.identifier, "_"),1268 .main_token = try c.addToken(.identifier, "_"),
1271 .data = .{ .lhs = undefined, .rhs = undefined },1269 .data = undefined,
1272 });1270 });
1273 return c.addNode(.{1271 return c.addNode(.{
1274 .tag = .assign,1272 .tag = .assign,
...@@ -1510,7 +1508,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1510,7 +1508,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1510 .rhs = try c.addNode(.{1508 .rhs = try c.addNode(.{
1511 .tag = .integer_literal,1509 .tag = .integer_literal,
1512 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{payload.count}),1510 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{payload.count}),
1513 .data = .{ .lhs = undefined, .rhs = undefined },1511 .data = undefined,
1514 }),1512 }),
1515 },1513 },
1516 });1514 });
...@@ -1519,7 +1517,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1519,7 +1517,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1519 const payload = node.castTag(.empty_array).?.data;1517 const payload = node.castTag(.empty_array).?.data;
15201518
1521 const type_expr = try renderArrayType(c, 0, payload);1519 const type_expr = try renderArrayType(c, 0, payload);
1522 return renderArrayInit(c, 0, &.{});1520 return renderArrayInit(c, type_expr, &.{});
1523 },1521 },
1524 .array_init => {1522 .array_init => {
1525 const payload = node.castTag(.array_init).?.data;1523 const payload = node.castTag(.array_init).?.data;
...@@ -1534,15 +1532,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1534,15 +1532,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1534 .@"struct", .@"union" => return renderRecord(c, node),1532 .@"struct", .@"union" => return renderRecord(c, node),
1535 .@"enum" => {1533 .@"enum" => {
1536 const payload = node.castTag(.@"enum").?.data;1534 const payload = node.castTag(.@"enum").?.data;
1535 _ = try c.addToken(.keyword_extern, "extern");
1537 const enum_tok = try c.addToken(.keyword_enum, "enum");1536 const enum_tok = try c.addToken(.keyword_enum, "enum");
15381537 _ = try c.addToken(.l_paren, "(");
1538 const arg_expr = try renderNode(c, payload.int_type);
1539 _ = try c.addToken(.r_paren, ")");
1539 _ = try c.addToken(.l_brace, "{");1540 _ = try c.addToken(.l_brace, "{");
1540 const members = try c.gpa.alloc(NodeIndex, std.math.max(payload.len + 1, 1));1541 const members = try c.gpa.alloc(NodeIndex, std.math.max(payload.fields.len + 1, 1));
1541 defer c.gpa.free(members);1542 defer c.gpa.free(members);
1542 members[0] = 0;1543 members[0] = 0;
1543 members[1] = 0;
15441544
1545 for (payload) |field, i| {1545 for (payload.fields) |field, i| {
1546 const name_tok = try c.addIdentifier(field.name);1546 const name_tok = try c.addIdentifier(field.name);
1547 const value_expr = if (field.value) |some| blk: {1547 const value_expr = if (field.value) |some| blk: {
1548 _ = try c.addToken(.equal, "=");1548 _ = try c.addToken(.equal, "=");
...@@ -1560,7 +1560,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1560,7 +1560,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1560 _ = try c.addToken(.comma, ",");1560 _ = try c.addToken(.comma, ",");
1561 }1561 }
1562 // make non-exhaustive1562 // make non-exhaustive
1563 members[payload.len] = try c.addNode(.{1563 members[payload.fields.len] = try c.addNode(.{
1564 .tag = .container_field_init,1564 .tag = .container_field_init,
1565 .main_token = try c.addIdentifier("_"),1565 .main_token = try c.addIdentifier("_"),
1566 .data = .{1566 .data = .{
...@@ -1571,26 +1571,18 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1571,26 +1571,18 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1571 _ = try c.addToken(.comma, ",");1571 _ = try c.addToken(.comma, ",");
1572 _ = try c.addToken(.r_brace, "}");1572 _ = try c.addToken(.r_brace, "}");
15731573
1574 if (members.len <= 2) {1574 const span = try c.listToSpan(members);
1575 return c.addNode(.{1575 return c.addNode(.{
1576 .tag = .container_decl_two_comma,1576 .tag = .container_decl_arg_comma,
1577 .main_token = enum_tok,1577 .main_token = enum_tok,
1578 .data = .{1578 .data = .{
1579 .lhs = members[0],1579 .lhs = arg_expr,
1580 .rhs = members[1],1580 .rhs = try c.addExtra(NodeSubRange{
1581 },1581 .start = span.start,
1582 });1582 .end = span.end,
1583 } else {1583 }),
1584 const span = try c.listToSpan(members);1584 },
1585 return c.addNode(.{1585 });
1586 .tag = .container_decl_comma,
1587 .main_token = enum_tok,
1588 .data = .{
1589 .lhs = span.start,
1590 .rhs = span.end,
1591 },
1592 });
1593 }
1594 },1586 },
1595 .enum_redecl => {1587 .enum_redecl => {
1596 const payload = node.castTag(.enum_redecl).?.data;1588 const payload = node.castTag(.enum_redecl).?.data;
...@@ -1701,12 +1693,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1701,12 +1693,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1701 });1693 });
1702 }1694 }
1703 },1695 },
1696 .@"anytype" => unreachable, // Handled in renderParams
1704 }1697 }
1705}1698}
17061699
1707fn renderRecord(c: *Context, node: Node) !NodeIndex {1700fn renderRecord(c: *Context, node: Node) !NodeIndex {
1708 const payload = @fieldParentPtr(Payload.Record, "base", node.ptr_otherwise).data;1701 const payload = @fieldParentPtr(Payload.Record, "base", node.ptr_otherwise).data;
1709 if (payload.is_packed) _ = try c.addToken(.keyword_packed, "packed");1702 if (payload.is_packed)
1703 _ = try c.addToken(.keyword_packed, "packed")
1704 else
1705 _ = try c.addToken(.keyword_extern, "extern");
1710 const kind_tok = if (node.tag() == .@"struct")1706 const kind_tok = if (node.tag() == .@"struct")
1711 try c.addToken(.keyword_struct, "struct")1707 try c.addToken(.keyword_struct, "struct")
1712 else1708 else
...@@ -1829,7 +1825,7 @@ fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {...@@ -1829,7 +1825,7 @@ fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
1829 const len_expr = try c.addNode(.{1825 const len_expr = try c.addNode(.{
1830 .tag = .integer_literal,1826 .tag = .integer_literal,
1831 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{len}),1827 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{len}),
1832 .data = .{ .lhs = undefined, .rhs = undefined },1828 .data = undefined,
1833 });1829 });
1834 _ = try c.addToken(.r_bracket, "]");1830 _ = try c.addToken(.r_bracket, "]");
1835 const elem_type_expr = try renderNode(c, elem_type);1831 const elem_type_expr = try renderNode(c, elem_type);
...@@ -1920,6 +1916,8 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -1920,6 +1916,8 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1920 .negate_wrap,1916 .negate_wrap,
1921 .bit_not,1917 .bit_not,
1922 .func,1918 .func,
1919 .call,
1920 .array_type,
1923 => {1921 => {
1924 // no grouping needed1922 // no grouping needed
1925 return renderNode(c, node);1923 return renderNode(c, node);
...@@ -1954,7 +1952,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -1954,7 +1952,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1954 .array_cat,1952 .array_cat,
1955 .array_filler,1953 .array_filler,
1956 .@"if",1954 .@"if",
1957 .call,
1958 .@"enum",1955 .@"enum",
1959 .@"struct",1956 .@"struct",
1960 .@"union",1957 .@"union",
...@@ -1962,7 +1959,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -1962,7 +1959,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1962 .tuple,1959 .tuple,
1963 .container_init,1960 .container_init,
1964 .block,1961 .block,
1965 .array_type,
1966 => return c.addNode(.{1962 => return c.addNode(.{
1967 .tag = .grouped_expression,1963 .tag = .grouped_expression,
1968 .main_token = try c.addToken(.l_paren, "("),1964 .main_token = try c.addToken(.l_paren, "("),
...@@ -2161,7 +2157,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {...@@ -2161,7 +2157,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
2161 const res = try c.addNode(.{2157 const res = try c.addNode(.{
2162 .tag = .integer_literal,2158 .tag = .integer_literal,
2163 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{some}),2159 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{some}),
2164 .data = .{ .lhs = undefined, .rhs = undefined },2160 .data = undefined,
2165 });2161 });
2166 _ = try c.addToken(.r_paren, ")");2162 _ = try c.addToken(.r_paren, ")");
2167 break :blk res;2163 break :blk res;
...@@ -2173,7 +2169,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {...@@ -2173,7 +2169,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
2173 const res = try c.addNode(.{2169 const res = try c.addNode(.{
2174 .tag = .string_literal,2170 .tag = .string_literal,
2175 .main_token = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(some)}),2171 .main_token = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(some)}),
2176 .data = .{ .lhs = undefined, .rhs = undefined },2172 .data = undefined,
2177 });2173 });
2178 _ = try c.addToken(.r_paren, ")");2174 _ = try c.addToken(.r_paren, ")");
2179 break :blk res;2175 break :blk res;
...@@ -2232,39 +2228,10 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2232,39 +2228,10 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2232 const fn_token = try c.addToken(.keyword_fn, "fn");2228 const fn_token = try c.addToken(.keyword_fn, "fn");
2233 if (payload.name) |some| _ = try c.addIdentifier(some);2229 if (payload.name) |some| _ = try c.addIdentifier(some);
22342230
2235 _ = try c.addToken(.l_paren, "(");2231 const params = try renderParams(c, payload.params, payload.is_var_args);
2236 const first = if (payload.params.len != 0) blk: {2232 defer params.deinit();
2237 const param = payload.params[0];
2238 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
2239 if (param.name) |some| {
2240 _ = try c.addIdentifier(some);
2241 _ = try c.addToken(.colon, ":");
2242 }
2243 break :blk try renderNode(c, param.type);
2244 } else 0;
2245
2246 var span: NodeSubRange = undefined;2233 var span: NodeSubRange = undefined;
2247 if (payload.params.len > 1) {2234 if (params.items.len > 1) span = try c.listToSpan(params.items);
2248 var params = try c.gpa.alloc(NodeIndex, payload.params.len);
2249 defer c.gpa.free(params);
2250
2251 params[0] = first;
2252 for (payload.params[1..]) |param, i| {
2253 _ = try c.addToken(.comma, ",");
2254 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
2255 if (param.name) |some| {
2256 _ = try c.addIdentifier(some);
2257 _ = try c.addToken(.colon, ":");
2258 }
2259 params[i + 1] = try renderNode(c, param.type);
2260 }
2261 span = try c.listToSpan(params);
2262 }
2263 if (payload.is_var_args) {
2264 if (payload.params.len != 0) _ = try c.addToken(.comma, ",");
2265 _ = try c.addToken(.ellipsis3, "...");
2266 }
2267 _ = try c.addToken(.r_paren, ")");
22682235
2269 const align_expr = if (payload.alignment) |some| blk: {2236 const align_expr = if (payload.alignment) |some| blk: {
2270 _ = try c.addToken(.keyword_align, "align");2237 _ = try c.addToken(.keyword_align, "align");
...@@ -2272,7 +2239,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2272,7 +2239,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2272 const res = try c.addNode(.{2239 const res = try c.addNode(.{
2273 .tag = .integer_literal,2240 .tag = .integer_literal,
2274 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{some}),2241 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{some}),
2275 .data = .{ .lhs = undefined, .rhs = undefined },2242 .data = undefined,
2276 });2243 });
2277 _ = try c.addToken(.r_paren, ")");2244 _ = try c.addToken(.r_paren, ")");
2278 break :blk res;2245 break :blk res;
...@@ -2284,7 +2251,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2284,7 +2251,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2284 const res = try c.addNode(.{2251 const res = try c.addNode(.{
2285 .tag = .string_literal,2252 .tag = .string_literal,
2286 .main_token = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(some)}),2253 .main_token = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(some)}),
2287 .data = .{ .lhs = undefined, .rhs = undefined },2254 .data = undefined,
2288 });2255 });
2289 _ = try c.addToken(.r_paren, ")");2256 _ = try c.addToken(.r_paren, ")");
2290 break :blk res;2257 break :blk res;
...@@ -2296,8 +2263,8 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2296,8 +2263,8 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2296 _ = try c.addToken(.period, ".");2263 _ = try c.addToken(.period, ".");
2297 const res = try c.addNode(.{2264 const res = try c.addNode(.{
2298 .tag = .enum_literal,2265 .tag = .enum_literal,
2299 .main_token = try c.addTokenFmt(.identifier, "{}", .{some}),2266 .main_token = try c.addTokenFmt(.identifier, "{s}", .{@tagName(some)}),
2300 .data = .{ .lhs = undefined, .rhs = undefined },2267 .data = undefined,
2301 });2268 });
2302 _ = try c.addToken(.r_paren, ")");2269 _ = try c.addToken(.r_paren, ")");
2303 break :blk res;2270 break :blk res;
...@@ -2307,12 +2274,12 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2307,12 +2274,12 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
23072274
2308 const fn_proto = try blk: {2275 const fn_proto = try blk: {
2309 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {2276 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {
2310 if (payload.params.len < 2)2277 if (params.items.len < 2)
2311 break :blk c.addNode(.{2278 break :blk c.addNode(.{
2312 .tag = .fn_proto_simple,2279 .tag = .fn_proto_simple,
2313 .main_token = fn_token,2280 .main_token = fn_token,
2314 .data = .{2281 .data = .{
2315 .lhs = first,2282 .lhs = params.items[0],
2316 .rhs = return_type_expr,2283 .rhs = return_type_expr,
2317 },2284 },
2318 })2285 })
...@@ -2329,13 +2296,13 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -2329,13 +2296,13 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
2329 },2296 },
2330 });2297 });
2331 }2298 }
2332 if (payload.params.len < 2)2299 if (params.items.len < 2)
2333 break :blk c.addNode(.{2300 break :blk c.addNode(.{
2334 .tag = .fn_proto_one,2301 .tag = .fn_proto_one,
2335 .main_token = fn_token,2302 .main_token = fn_token,
2336 .data = .{2303 .data = .{
2337 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{2304 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{
2338 .param = first,2305 .param = params.items[0],
2339 .align_expr = align_expr,2306 .align_expr = align_expr,
2340 .section_expr = section_expr,2307 .section_expr = section_expr,
2341 .callconv_expr = callconv_expr,2308 .callconv_expr = callconv_expr,
...@@ -2383,35 +2350,10 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {...@@ -2383,35 +2350,10 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2383 const fn_token = try c.addToken(.keyword_fn, "fn");2350 const fn_token = try c.addToken(.keyword_fn, "fn");
2384 _ = try c.addIdentifier(payload.name);2351 _ = try c.addIdentifier(payload.name);
23852352
2386 _ = try c.addToken(.l_paren, "(");2353 const params = try renderParams(c, payload.params, false);
2387 const first = if (payload.params.len != 0) blk: {2354 defer params.deinit();
2388 const param = payload.params[0];
2389 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
2390 if (param.name) |some| {
2391 _ = try c.addIdentifier(some);
2392 _ = try c.addToken(.colon, ":");
2393 }
2394 break :blk try renderNode(c, param.type);
2395 } else 0;
2396
2397 var span: NodeSubRange = undefined;2355 var span: NodeSubRange = undefined;
2398 if (payload.params.len > 1) {2356 if (params.items.len > 1) span = try c.listToSpan(params.items);
2399 var params = try c.gpa.alloc(NodeIndex, payload.params.len);
2400 defer c.gpa.free(params);
2401
2402 params[0] = first;
2403 for (payload.params[1..]) |param, i| {
2404 _ = try c.addToken(.comma, ",");
2405 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
2406 if (param.name) |some| {
2407 _ = try c.addIdentifier(some);
2408 _ = try c.addToken(.colon, ":");
2409 }
2410 params[i + 1] = try renderNode(c, param.type);
2411 }
2412 span = try c.listToSpan(params);
2413 }
2414 _ = try c.addToken(.r_paren, ")");
24152357
2416 const callconv_expr = blk: {2358 const callconv_expr = blk: {
2417 _ = try c.addToken(.keyword_callconv, "callconv");2359 _ = try c.addToken(.keyword_callconv, "callconv");
...@@ -2420,7 +2362,7 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {...@@ -2420,7 +2362,7 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2420 const res = try c.addNode(.{2362 const res = try c.addNode(.{
2421 .tag = .enum_literal,2363 .tag = .enum_literal,
2422 .main_token = try c.addToken(.identifier, "Inline"),2364 .main_token = try c.addToken(.identifier, "Inline"),
2423 .data = .{ .lhs = undefined, .rhs = undefined },2365 .data = undefined,
2424 });2366 });
2425 _ = try c.addToken(.r_paren, ")");2367 _ = try c.addToken(.r_paren, ")");
2426 break :blk res;2368 break :blk res;
...@@ -2428,13 +2370,13 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {...@@ -2428,13 +2370,13 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2428 const return_type_expr = try renderNode(c, payload.return_type);2370 const return_type_expr = try renderNode(c, payload.return_type);
24292371
2430 const fn_proto = try blk: {2372 const fn_proto = try blk: {
2431 if (payload.params.len < 2)2373 if (params.items.len < 2)
2432 break :blk c.addNode(.{2374 break :blk c.addNode(.{
2433 .tag = .fn_proto_one,2375 .tag = .fn_proto_one,
2434 .main_token = fn_token,2376 .main_token = fn_token,
2435 .data = .{2377 .data = .{
2436 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{2378 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{
2437 .param = first,2379 .param = params.items[0],
2438 .align_expr = 0,2380 .align_expr = 0,
2439 .section_expr = 0,2381 .section_expr = 0,
2440 .callconv_expr = callconv_expr,2382 .callconv_expr = callconv_expr,
...@@ -2467,3 +2409,32 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {...@@ -2467,3 +2409,32 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
2467 },2409 },
2468 });2410 });
2469}2411}
2412
2413fn renderParams(c: *Context, params: []Payload.Param, is_var_args: bool) !std.ArrayList(NodeIndex) {
2414 _ = try c.addToken(.l_paren, "(");
2415 var rendered = std.ArrayList(NodeIndex).init(c.gpa);
2416 errdefer rendered.deinit();
2417 try rendered.ensureCapacity(std.math.max(params.len, 1));
2418
2419 for (params) |param, i| {
2420 if (i != 0) _ = try c.addToken(.comma, ",");
2421 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
2422 if (param.name) |some| {
2423 _ = try c.addIdentifier(some);
2424 _ = try c.addToken(.colon, ":");
2425 }
2426 if (param.type.tag() == .@"anytype") {
2427 _ = try c.addToken(.keyword_anytype, "anytype");
2428 continue;
2429 }
2430 rendered.appendAssumeCapacity(try renderNode(c, param.type));
2431 }
2432 if (is_var_args) {
2433 if (params.len != 0) _ = try c.addToken(.comma, ",");
2434 _ = try c.addToken(.ellipsis3, "...");
2435 }
2436 _ = try c.addToken(.r_paren, ")");
2437
2438 if (rendered.items.len == 0) rendered.appendAssumeCapacity(0);
2439 return rendered;
2440}