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" {
36693669 );
36703670}
36713671
3672//test "zig fmt: C var args" {
3673// try testCanonical(
3674// \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
3675// \\
3676// );
3677//}
3672test "zig fmt: C var args" {
3673 try testCanonical(
3674 \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
3675 \\
3676 );
3677}
36783678
36793679//test "zig fmt: Only indent multiline string literals in function calls" {
36803680// 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
13081308 .r_paren => break,
13091309 .comma => {
13101310 try renderToken(ais, tree, last_param_token, .space); // ,
1311 last_param_token += 1;
1311 continue;
13121312 },
13131313 else => {}, // Parameter type without a name.
13141314 }
src/translate_c.zig+30-13
......@@ -990,7 +990,10 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node {
990990 }));
991991 }
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 });
994997 } else blk: {
995998 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {});
996999 break :blk Tag.opaque_literal.init();
......@@ -1540,8 +1543,8 @@ fn finishBoolExpr(
15401543 }
15411544 },
15421545 .Pointer => {
1543 // node == null
1544 return Tag.equal.create(c.arena, .{ .lhs = node, .rhs = Tag.null_literal.init() });
1546 // node != null
1547 return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.null_literal.init() });
15451548 },
15461549 .Typedef => {
15471550 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
......@@ -1675,7 +1678,8 @@ fn transStringLiteralAsArray(
16751678 const ty = expr_base.getType().getTypePtr();
16761679 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 });
16791683 const init_list = try c.arena.alloc(Node, array_size);
16801684
16811685 var i: c_uint = 0;
......@@ -2668,7 +2672,7 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat
26682672 return Tag.bit_not.create(c.arena, try transExpr(c, scope, op_expr, .used));
26692673 },
26702674 .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));
26722676 },
26732677 .Extension => {
26742678 return transExpr(c, scope, stmt.getSubExpr(), used);
......@@ -2969,8 +2973,15 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node {
29692973
29702974fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {
29712975 // TODO use something more accurate
2972 const dbl = stmt.getValueAsApproximateDouble();
2973 const node = try transCreateNodeNumber(c, dbl, .float);
2976 var dbl = stmt.getValueAsApproximateDouble();
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);
29742985 return maybeSuppressResult(c, scope, used, node);
29752986}
29762987
......@@ -3004,8 +3015,11 @@ fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang
30043015 },
30053016 };
30063017 defer cond_scope.deinit();
3007 const cond_node = try transBoolExpr(c, &cond_scope.base, cond_expr, .used);
3008 var then_body = try Tag.identifier.create(c.arena, mangled_name);
3018
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;
30093023 if (!res_is_bool and isBoolRes(init_node)) {
30103024 then_body = try Tag.bool_to_int.create(c.arena, then_body);
30113025 }
......@@ -3489,11 +3503,13 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {
34893503 else => @compileError("unimplemented"),
34903504 }
34913505
3492 const big: math.big.int.Const = .{ .limbs = limbs, .positive = !is_negative };
3506 const big: math.big.int.Const = .{ .limbs = limbs, .positive = true };
34933507 const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {
34943508 error.OutOfMemory => return error.OutOfMemory,
34953509 };
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;
34973513}
34983514
34993515fn transCreateNodeNumber(c: *Context, num: anytype, num_kind: enum { int, float }) !Node {
......@@ -3567,7 +3583,7 @@ fn transCreateNodeShiftOp(
35673583
35683584 const rhs_type = try qualTypeToLog2IntRef(c, stmt.getType(), rhs_location);
35693585 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
35723588 return transCreateNodeInfixOp(c, scope, op, lhs, rhs_casted, used);
35733589}
......@@ -3622,7 +3638,8 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
36223638 const is_volatile = child_qt.isVolatileQualified();
36233639 const elem_type = try transQualType(c, child_qt, source_loc);
36243640 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);
36263643 }
36273644
36283645 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 {
491491
492492 pub const Enum = struct {
493493 base: Payload,
494 data: []Field,
494 data: struct {
495 int_type: Node,
496 fields: []Field,
497 },
495498
496499 pub const Field = struct {
497500 name: []const u8,
......@@ -825,11 +828,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
825828 .main_token = try c.addToken(.identifier, "void"),
826829 .data = undefined,
827830 }),
828 .@"anytype" => return c.addNode(.{
829 .tag = .@"anytype",
830 .main_token = try c.addToken(.keyword_anytype, "anytype"),
831 .data = undefined,
832 }),
833831 .noreturn_type => return c.addNode(.{
834832 .tag = .identifier,
835833 .main_token = try c.addToken(.identifier, "noreturn"),
......@@ -946,7 +944,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
946944 const payload = node.castTag(.char_literal).?.data;
947945 return c.addNode(.{
948946 .tag = .identifier,
949 .main_token = try c.addToken(.string_literal, payload),
947 .main_token = try c.addToken(.char_literal, payload),
950948 .data = undefined,
951949 });
952950 },
......@@ -1268,7 +1266,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
12681266 const lhs = try c.addNode(.{
12691267 .tag = .identifier,
12701268 .main_token = try c.addToken(.identifier, "_"),
1271 .data = .{ .lhs = undefined, .rhs = undefined },
1269 .data = undefined,
12721270 });
12731271 return c.addNode(.{
12741272 .tag = .assign,
......@@ -1510,7 +1508,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
15101508 .rhs = try c.addNode(.{
15111509 .tag = .integer_literal,
15121510 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{payload.count}),
1513 .data = .{ .lhs = undefined, .rhs = undefined },
1511 .data = undefined,
15141512 }),
15151513 },
15161514 });
......@@ -1519,7 +1517,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
15191517 const payload = node.castTag(.empty_array).?.data;
15201518
15211519 const type_expr = try renderArrayType(c, 0, payload);
1522 return renderArrayInit(c, 0, &.{});
1520 return renderArrayInit(c, type_expr, &.{});
15231521 },
15241522 .array_init => {
15251523 const payload = node.castTag(.array_init).?.data;
......@@ -1534,15 +1532,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
15341532 .@"struct", .@"union" => return renderRecord(c, node),
15351533 .@"enum" => {
15361534 const payload = node.castTag(.@"enum").?.data;
1535 _ = try c.addToken(.keyword_extern, "extern");
15371536 const enum_tok = try c.addToken(.keyword_enum, "enum");
1538
1537 _ = try c.addToken(.l_paren, "(");
1538 const arg_expr = try renderNode(c, payload.int_type);
1539 _ = try c.addToken(.r_paren, ")");
15391540 _ = 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));
15411542 defer c.gpa.free(members);
15421543 members[0] = 0;
1543 members[1] = 0;
15441544
1545 for (payload) |field, i| {
1545 for (payload.fields) |field, i| {
15461546 const name_tok = try c.addIdentifier(field.name);
15471547 const value_expr = if (field.value) |some| blk: {
15481548 _ = try c.addToken(.equal, "=");
......@@ -1560,7 +1560,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
15601560 _ = try c.addToken(.comma, ",");
15611561 }
15621562 // make non-exhaustive
1563 members[payload.len] = try c.addNode(.{
1563 members[payload.fields.len] = try c.addNode(.{
15641564 .tag = .container_field_init,
15651565 .main_token = try c.addIdentifier("_"),
15661566 .data = .{
......@@ -1571,26 +1571,18 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
15711571 _ = try c.addToken(.comma, ",");
15721572 _ = try c.addToken(.r_brace, "}");
15731573
1574 if (members.len <= 2) {
1575 return c.addNode(.{
1576 .tag = .container_decl_two_comma,
1577 .main_token = enum_tok,
1578 .data = .{
1579 .lhs = members[0],
1580 .rhs = members[1],
1581 },
1582 });
1583 } else {
1584 const span = try c.listToSpan(members);
1585 return c.addNode(.{
1586 .tag = .container_decl_comma,
1587 .main_token = enum_tok,
1588 .data = .{
1589 .lhs = span.start,
1590 .rhs = span.end,
1591 },
1592 });
1593 }
1574 const span = try c.listToSpan(members);
1575 return c.addNode(.{
1576 .tag = .container_decl_arg_comma,
1577 .main_token = enum_tok,
1578 .data = .{
1579 .lhs = arg_expr,
1580 .rhs = try c.addExtra(NodeSubRange{
1581 .start = span.start,
1582 .end = span.end,
1583 }),
1584 },
1585 });
15941586 },
15951587 .enum_redecl => {
15961588 const payload = node.castTag(.enum_redecl).?.data;
......@@ -1701,12 +1693,16 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
17011693 });
17021694 }
17031695 },
1696 .@"anytype" => unreachable, // Handled in renderParams
17041697 }
17051698}
17061699
17071700fn renderRecord(c: *Context, node: Node) !NodeIndex {
17081701 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");
17101706 const kind_tok = if (node.tag() == .@"struct")
17111707 try c.addToken(.keyword_struct, "struct")
17121708 else
......@@ -1829,7 +1825,7 @@ fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
18291825 const len_expr = try c.addNode(.{
18301826 .tag = .integer_literal,
18311827 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{len}),
1832 .data = .{ .lhs = undefined, .rhs = undefined },
1828 .data = undefined,
18331829 });
18341830 _ = try c.addToken(.r_bracket, "]");
18351831 const elem_type_expr = try renderNode(c, elem_type);
......@@ -1920,6 +1916,8 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
19201916 .negate_wrap,
19211917 .bit_not,
19221918 .func,
1919 .call,
1920 .array_type,
19231921 => {
19241922 // no grouping needed
19251923 return renderNode(c, node);
......@@ -1954,7 +1952,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
19541952 .array_cat,
19551953 .array_filler,
19561954 .@"if",
1957 .call,
19581955 .@"enum",
19591956 .@"struct",
19601957 .@"union",
......@@ -1962,7 +1959,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
19621959 .tuple,
19631960 .container_init,
19641961 .block,
1965 .array_type,
19661962 => return c.addNode(.{
19671963 .tag = .grouped_expression,
19681964 .main_token = try c.addToken(.l_paren, "("),
......@@ -2161,7 +2157,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
21612157 const res = try c.addNode(.{
21622158 .tag = .integer_literal,
21632159 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{some}),
2164 .data = .{ .lhs = undefined, .rhs = undefined },
2160 .data = undefined,
21652161 });
21662162 _ = try c.addToken(.r_paren, ")");
21672163 break :blk res;
......@@ -2173,7 +2169,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
21732169 const res = try c.addNode(.{
21742170 .tag = .string_literal,
21752171 .main_token = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(some)}),
2176 .data = .{ .lhs = undefined, .rhs = undefined },
2172 .data = undefined,
21772173 });
21782174 _ = try c.addToken(.r_paren, ")");
21792175 break :blk res;
......@@ -2232,39 +2228,10 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
22322228 const fn_token = try c.addToken(.keyword_fn, "fn");
22332229 if (payload.name) |some| _ = try c.addIdentifier(some);
22342230
2235 _ = try c.addToken(.l_paren, "(");
2236 const first = if (payload.params.len != 0) blk: {
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
2231 const params = try renderParams(c, payload.params, payload.is_var_args);
2232 defer params.deinit();
22462233 var span: NodeSubRange = undefined;
2247 if (payload.params.len > 1) {
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, ")");
2234 if (params.items.len > 1) span = try c.listToSpan(params.items);
22682235
22692236 const align_expr = if (payload.alignment) |some| blk: {
22702237 _ = try c.addToken(.keyword_align, "align");
......@@ -2272,7 +2239,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
22722239 const res = try c.addNode(.{
22732240 .tag = .integer_literal,
22742241 .main_token = try c.addTokenFmt(.integer_literal, "{d}", .{some}),
2275 .data = .{ .lhs = undefined, .rhs = undefined },
2242 .data = undefined,
22762243 });
22772244 _ = try c.addToken(.r_paren, ")");
22782245 break :blk res;
......@@ -2284,7 +2251,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
22842251 const res = try c.addNode(.{
22852252 .tag = .string_literal,
22862253 .main_token = try c.addTokenFmt(.string_literal, "\"{s}\"", .{std.zig.fmtEscapes(some)}),
2287 .data = .{ .lhs = undefined, .rhs = undefined },
2254 .data = undefined,
22882255 });
22892256 _ = try c.addToken(.r_paren, ")");
22902257 break :blk res;
......@@ -2296,8 +2263,8 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
22962263 _ = try c.addToken(.period, ".");
22972264 const res = try c.addNode(.{
22982265 .tag = .enum_literal,
2299 .main_token = try c.addTokenFmt(.identifier, "{}", .{some}),
2300 .data = .{ .lhs = undefined, .rhs = undefined },
2266 .main_token = try c.addTokenFmt(.identifier, "{s}", .{@tagName(some)}),
2267 .data = undefined,
23012268 });
23022269 _ = try c.addToken(.r_paren, ")");
23032270 break :blk res;
......@@ -2307,12 +2274,12 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
23072274
23082275 const fn_proto = try blk: {
23092276 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {
2310 if (payload.params.len < 2)
2277 if (params.items.len < 2)
23112278 break :blk c.addNode(.{
23122279 .tag = .fn_proto_simple,
23132280 .main_token = fn_token,
23142281 .data = .{
2315 .lhs = first,
2282 .lhs = params.items[0],
23162283 .rhs = return_type_expr,
23172284 },
23182285 })
......@@ -2329,13 +2296,13 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
23292296 },
23302297 });
23312298 }
2332 if (payload.params.len < 2)
2299 if (params.items.len < 2)
23332300 break :blk c.addNode(.{
23342301 .tag = .fn_proto_one,
23352302 .main_token = fn_token,
23362303 .data = .{
23372304 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{
2338 .param = first,
2305 .param = params.items[0],
23392306 .align_expr = align_expr,
23402307 .section_expr = section_expr,
23412308 .callconv_expr = callconv_expr,
......@@ -2383,35 +2350,10 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
23832350 const fn_token = try c.addToken(.keyword_fn, "fn");
23842351 _ = try c.addIdentifier(payload.name);
23852352
2386 _ = try c.addToken(.l_paren, "(");
2387 const first = if (payload.params.len != 0) blk: {
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
2353 const params = try renderParams(c, payload.params, false);
2354 defer params.deinit();
23972355 var span: NodeSubRange = undefined;
2398 if (payload.params.len > 1) {
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, ")");
2356 if (params.items.len > 1) span = try c.listToSpan(params.items);
24152357
24162358 const callconv_expr = blk: {
24172359 _ = try c.addToken(.keyword_callconv, "callconv");
......@@ -2420,7 +2362,7 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
24202362 const res = try c.addNode(.{
24212363 .tag = .enum_literal,
24222364 .main_token = try c.addToken(.identifier, "Inline"),
2423 .data = .{ .lhs = undefined, .rhs = undefined },
2365 .data = undefined,
24242366 });
24252367 _ = try c.addToken(.r_paren, ")");
24262368 break :blk res;
......@@ -2428,13 +2370,13 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
24282370 const return_type_expr = try renderNode(c, payload.return_type);
24292371
24302372 const fn_proto = try blk: {
2431 if (payload.params.len < 2)
2373 if (params.items.len < 2)
24322374 break :blk c.addNode(.{
24332375 .tag = .fn_proto_one,
24342376 .main_token = fn_token,
24352377 .data = .{
24362378 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{
2437 .param = first,
2379 .param = params.items[0],
24382380 .align_expr = 0,
24392381 .section_expr = 0,
24402382 .callconv_expr = callconv_expr,
......@@ -2467,3 +2409,32 @@ fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
24672409 },
24682410 });
24692411}
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}