authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-14 15:35:51+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:40:42+02:00
logc4dfabf4dcfc29f48356e3c5f762f1ca2c21f088
tree4a24c653e0e25bf882c8f38ecc9728bd8adec1f2
parentf191251ddb424eba7384d31fa2d50e50586f3993
signature Commit is signed but in an unrecognized format.

translate-c: render macro functions, use cast type as return type

Closes #8004

2 files changed, 191 insertions(+), 97 deletions(-)

src/translate_c.zig+6-2
...@@ -4099,14 +4099,18 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {...@@ -4099,14 +4099,18 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
4099 const br = blk_last.castTag(.break_val).?;4099 const br = blk_last.castTag(.break_val).?;
4100 break :blk br.data.val;4100 break :blk br.data.val;
4101 } else expr;4101 } else expr;
4102 const typeof = try Tag.typeof.create(c.arena, typeof_arg);4102 const return_type = if (typeof_arg.castTag(.std_meta_cast)) |some|
4103 some.data.lhs
4104 else
4105 try Tag.typeof.create(c.arena, typeof_arg);
4106
4103 const return_expr = try Tag.@"return".create(c.arena, expr);4107 const return_expr = try Tag.@"return".create(c.arena, expr);
4104 try block_scope.statements.append(return_expr);4108 try block_scope.statements.append(return_expr);
41054109
4106 const fn_decl = try Tag.pub_inline_fn.create(c.arena, .{4110 const fn_decl = try Tag.pub_inline_fn.create(c.arena, .{
4107 .name = m.name,4111 .name = m.name,
4108 .params = try c.arena.dupe(ast.Payload.Param, fn_params.items),4112 .params = try c.arena.dupe(ast.Payload.Param, fn_params.items),
4109 .return_type = typeof,4113 .return_type = return_type,
4110 .body = try block_scope.complete(c),4114 .body = try block_scope.complete(c),
4111 });4115 });
4112 _ = try c.global_scope.macro_table.put(m.name, fn_decl);4116 _ = try c.global_scope.macro_table.put(m.name, fn_decl);
src/translate_c/ast.zig+185-95
...@@ -615,9 +615,15 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {...@@ -615,9 +615,15 @@ pub fn render(gpa: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
615 defer ctx.extra_data.deinit(gpa);615 defer ctx.extra_data.deinit(gpa);
616 defer ctx.tokens.deinit(gpa);616 defer ctx.tokens.deinit(gpa);
617617
618 // Estimate that each top level node has 25 child nodes.618 // Estimate that each top level node has 10 child nodes.
619 const estimated_node_count = nodes.len * 25;619 const estimated_node_count = nodes.len * 10;
620 try ctx.nodes.ensureCapacity(gpa, estimated_node_count);620 try ctx.nodes.ensureCapacity(gpa, estimated_node_count);
621 // Estimate that each each node has 2 tokens.
622 const estimated_tokens_count = estimated_node_count * 2;
623 try ctx.tokens.ensureCapacity(gpa, estimated_tokens_count);
624 // Estimate that each each token is 3 bytes long.
625 const estimated_buf_len = estimated_tokens_count * 3;
626 try ctx.buf.ensureCapacity(estimated_buf_len);
621627
622 ctx.nodes.appendAssumeCapacity(.{628 ctx.nodes.appendAssumeCapacity(.{
623 .tag = .root,629 .tag = .root,
...@@ -776,74 +782,47 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -776,74 +782,47 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
776 .null_literal => return c.addNode(.{782 .null_literal => return c.addNode(.{
777 .tag = .null_literal,783 .tag = .null_literal,
778 .main_token = try c.addToken(.keyword_null, "null"),784 .main_token = try c.addToken(.keyword_null, "null"),
779 .data = .{785 .data = undefined,
780 .lhs = undefined,
781 .rhs = undefined,
782 },
783 }),786 }),
784 .undefined_literal => return c.addNode(.{787 .undefined_literal => return c.addNode(.{
785 .tag = .undefined_literal,788 .tag = .undefined_literal,
786 .main_token = try c.addToken(.keyword_undefined, "undefined"),789 .main_token = try c.addToken(.keyword_undefined, "undefined"),
787 .data = .{790 .data = undefined,
788 .lhs = undefined,
789 .rhs = undefined,
790 },
791 }),791 }),
792 .true_literal => return c.addNode(.{792 .true_literal => return c.addNode(.{
793 .tag = .true_literal,793 .tag = .true_literal,
794 .main_token = try c.addToken(.keyword_true, "true"),794 .main_token = try c.addToken(.keyword_true, "true"),
795 .data = .{795 .data = undefined,
796 .lhs = undefined,
797 .rhs = undefined,
798 },
799 }),796 }),
800 .false_literal => return c.addNode(.{797 .false_literal => return c.addNode(.{
801 .tag = .false_literal,798 .tag = .false_literal,
802 .main_token = try c.addToken(.keyword_false, "false"),799 .main_token = try c.addToken(.keyword_false, "false"),
803 .data = .{800 .data = undefined,
804 .lhs = undefined,
805 .rhs = undefined,
806 },
807 }),801 }),
808 .zero_literal => return c.addNode(.{802 .zero_literal => return c.addNode(.{
809 .tag = .integer_literal,803 .tag = .integer_literal,
810 .main_token = try c.addToken(.integer_literal, "0"),804 .main_token = try c.addToken(.integer_literal, "0"),
811 .data = .{805 .data = undefined,
812 .lhs = undefined,
813 .rhs = undefined,
814 },
815 }),806 }),
816 .one_literal => return c.addNode(.{807 .one_literal => return c.addNode(.{
817 .tag = .integer_literal,808 .tag = .integer_literal,
818 .main_token = try c.addToken(.integer_literal, "1"),809 .main_token = try c.addToken(.integer_literal, "1"),
819 .data = .{810 .data = undefined,
820 .lhs = undefined,
821 .rhs = undefined,
822 },
823 }),811 }),
824 .void_type => return c.addNode(.{812 .void_type => return c.addNode(.{
825 .tag = .identifier,813 .tag = .identifier,
826 .main_token = try c.addToken(.identifier, "void"),814 .main_token = try c.addToken(.identifier, "void"),
827 .data = .{815 .data = undefined,
828 .lhs = undefined,
829 .rhs = undefined,
830 },
831 }),816 }),
832 .@"anytype" => return c.addNode(.{817 .@"anytype" => return c.addNode(.{
833 .tag = .@"anytype",818 .tag = .@"anytype",
834 .main_token = try c.addToken(.keyword_anytype, "anytype"),819 .main_token = try c.addToken(.keyword_anytype, "anytype"),
835 .data = .{820 .data = undefined,
836 .lhs = undefined,
837 .rhs = undefined,
838 },
839 }),821 }),
840 .noreturn_type => return c.addNode(.{822 .noreturn_type => return c.addNode(.{
841 .tag = .identifier,823 .tag = .identifier,
842 .main_token = try c.addToken(.identifier, "noreturn"),824 .main_token = try c.addToken(.identifier, "noreturn"),
843 .data = .{825 .data = undefined,
844 .lhs = undefined,
845 .rhs = undefined,
846 },
847 }),826 }),
848 .@"continue" => return c.addNode(.{827 .@"continue" => return c.addNode(.{
849 .tag = .@"continue",828 .tag = .@"continue",
...@@ -853,6 +832,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -853,6 +832,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
853 .rhs = undefined,832 .rhs = undefined,
854 },833 },
855 }),834 }),
835 .return_void => return c.addNode(.{
836 .tag = .@"return",
837 .main_token = try c.addToken(.keyword_return, "return"),
838 .data = .{
839 .lhs = 0,
840 .rhs = undefined,
841 },
842 }),
856 .@"break" => {843 .@"break" => {
857 const payload = node.castTag(.@"break").?.data;844 const payload = node.castTag(.@"break").?.data;
858 const tok = try c.addToken(.keyword_break, "break");845 const tok = try c.addToken(.keyword_break, "break");
...@@ -885,15 +872,23 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -885,15 +872,23 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
885 },872 },
886 });873 });
887 },874 },
875 .@"return" => {
876 const payload = node.castTag(.@"return").?.data;
877 return c.addNode(.{
878 .tag = .@"return",
879 .main_token = try c.addToken(.keyword_return, "return"),
880 .data = .{
881 .lhs = try renderNode(c, payload),
882 .rhs = undefined,
883 },
884 });
885 },
888 .type => {886 .type => {
889 const payload = node.castTag(.type).?.data;887 const payload = node.castTag(.type).?.data;
890 return c.addNode(.{888 return c.addNode(.{
891 .tag = .identifier,889 .tag = .identifier,
892 .main_token = try c.addToken(.identifier, payload),890 .main_token = try c.addToken(.identifier, payload),
893 .data = .{891 .data = undefined,
894 .lhs = undefined,
895 .rhs = undefined,
896 },
897 });892 });
898 },893 },
899 .log2_int_type => {894 .log2_int_type => {
...@@ -901,10 +896,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -901,10 +896,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
901 return c.addNode(.{896 return c.addNode(.{
902 .tag = .identifier,897 .tag = .identifier,
903 .main_token = try c.addTokenFmt(.identifier, "u{d}", .{payload}),898 .main_token = try c.addTokenFmt(.identifier, "u{d}", .{payload}),
904 .data = .{899 .data = undefined,
905 .lhs = undefined,
906 .rhs = undefined,
907 },
908 });900 });
909 },901 },
910 .identifier => {902 .identifier => {
...@@ -912,10 +904,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -912,10 +904,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
912 return c.addNode(.{904 return c.addNode(.{
913 .tag = .identifier,905 .tag = .identifier,
914 .main_token = try c.addIdentifier(payload),906 .main_token = try c.addIdentifier(payload),
915 .data = .{907 .data = undefined,
916 .lhs = undefined,
917 .rhs = undefined,
918 },
919 });908 });
920 },909 },
921 .float_literal => {910 .float_literal => {
...@@ -923,10 +912,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -923,10 +912,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
923 return c.addNode(.{912 return c.addNode(.{
924 .tag = .float_literal,913 .tag = .float_literal,
925 .main_token = try c.addToken(.float_literal, payload),914 .main_token = try c.addToken(.float_literal, payload),
926 .data = .{915 .data = undefined,
927 .lhs = undefined,
928 .rhs = undefined,
929 },
930 });916 });
931 },917 },
932 .integer_literal => {918 .integer_literal => {
...@@ -934,10 +920,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -934,10 +920,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
934 return c.addNode(.{920 return c.addNode(.{
935 .tag = .integer_literal,921 .tag = .integer_literal,
936 .main_token = try c.addToken(.integer_literal, payload),922 .main_token = try c.addToken(.integer_literal, payload),
937 .data = .{923 .data = undefined,
938 .lhs = undefined,
939 .rhs = undefined,
940 },
941 });924 });
942 },925 },
943 .string_literal => {926 .string_literal => {
...@@ -945,10 +928,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -945,10 +928,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
945 return c.addNode(.{928 return c.addNode(.{
946 .tag = .identifier,929 .tag = .identifier,
947 .main_token = try c.addToken(.string_literal, payload),930 .main_token = try c.addToken(.string_literal, payload),
948 .data = .{931 .data = undefined,
949 .lhs = undefined,
950 .rhs = undefined,
951 },
952 });932 });
953 },933 },
954 .char_literal => {934 .char_literal => {
...@@ -956,10 +936,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -956,10 +936,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
956 return c.addNode(.{936 return c.addNode(.{
957 .tag = .identifier,937 .tag = .identifier,
958 .main_token = try c.addToken(.string_literal, payload),938 .main_token = try c.addToken(.string_literal, payload),
959 .data = .{939 .data = undefined,
960 .lhs = undefined,
961 .rhs = undefined,
962 },
963 });940 });
964 },941 },
965 .fail_decl => {942 .fail_decl => {
...@@ -976,10 +953,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -976,10 +953,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
976 const err_msg = try c.addNode(.{953 const err_msg = try c.addNode(.{
977 .tag = .string_literal,954 .tag = .string_literal,
978 .main_token = err_msg_tok,955 .main_token = err_msg_tok,
979 .data = .{956 .data = undefined,
980 .lhs = undefined,
981 .rhs = undefined,
982 },
983 });957 });
984 _ = try c.addToken(.r_paren, ")");958 _ = try c.addToken(.r_paren, ")");
985 const compile_error = try c.addNode(.{959 const compile_error = try c.addNode(.{
...@@ -1130,6 +1104,31 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1130,6 +1104,31 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1130 },1104 },
1131 });1105 });
1132 },1106 },
1107 .c_pointer, .single_pointer => {
1108 const payload = @fieldParentPtr(Payload.Pointer, "base", node.ptr_otherwise).data;
1109
1110 const asterisk = if (node.tag() == .single_pointer)
1111 try c.addToken(.asterisk, "*")
1112 else blk: {
1113 _ = try c.addToken(.l_bracket, "[");
1114 const res = try c.addToken(.asterisk, "*");
1115 _ = try c.addIdentifier("c");
1116 _ = try c.addToken(.r_bracket, "]");
1117 break :blk res;
1118 };
1119 if (payload.is_const) _ = try c.addToken(.keyword_const, "const");
1120 if (payload.is_volatile) _ = try c.addToken(.keyword_volatile, "volatile");
1121 const elem_type = try renderNode(c, payload.elem_type);
1122
1123 return c.addNode(.{
1124 .tag = .ptr_type_aligned,
1125 .main_token = asterisk,
1126 .data = .{
1127 .lhs = 0,
1128 .rhs = elem_type,
1129 },
1130 });
1131 },
1133 .add => return renderBinOp(c, node, .add, .plus, "+"),1132 .add => return renderBinOp(c, node, .add, .plus, "+"),
1134 .add_assign => return renderBinOp(c, node, .assign_add, .plus_equal, "+="),1133 .add_assign => return renderBinOp(c, node, .assign_add, .plus_equal, "+="),
1135 .add_wrap => return renderBinOp(c, node, .add_wrap, .plus_percent, "+%"),1134 .add_wrap => return renderBinOp(c, node, .add_wrap, .plus_percent, "+%"),
...@@ -1229,6 +1228,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1229,6 +1228,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1229 });1228 });
1230 },1229 },
1231 .func => return renderFunc(c, node),1230 .func => return renderFunc(c, node),
1231 .pub_inline_fn => return renderMacroFunc(c, node),
1232 .discard => {1232 .discard => {
1233 const payload = node.castTag(.discard).?.data;1233 const payload = node.castTag(.discard).?.data;
1234 const lhs = try c.addNode(.{1234 const lhs = try c.addNode(.{
...@@ -1300,6 +1300,9 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -1300,6 +1300,9 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1300 .type,1300 .type,
1301 .array_access,1301 .array_access,
1302 .align_cast,1302 .align_cast,
1303 .optional_type,
1304 .c_pointer,
1305 .single_pointer,
1303 => {1306 => {
1304 // no grouping needed1307 // no grouping needed
1305 return renderNode(c, node);1308 return renderNode(c, node);
...@@ -1310,7 +1313,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -1310,7 +1313,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1310 .bit_not,1313 .bit_not,
1311 .opaque_literal,1314 .opaque_literal,
1312 .not,1315 .not,
1313 .optional_type,
1314 .address_of,1316 .address_of,
1315 .unwrap,1317 .unwrap,
1316 .deref,1318 .deref,
...@@ -1350,8 +1352,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -1350,8 +1352,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
1350 .tuple,1352 .tuple,
1351 .container_init,1353 .container_init,
1352 .block,1354 .block,
1353 .c_pointer,
1354 .single_pointer,
1355 .array_type,1355 .array_type,
1356 => return c.addNode(.{1356 => return c.addNode(.{
1357 .tag = .grouped_expression,1357 .tag = .grouped_expression,
...@@ -1439,10 +1439,7 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde...@@ -1439,10 +1439,7 @@ fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeInde
1439 const std_node = try c.addNode(.{1439 const std_node = try c.addNode(.{
1440 .tag = .string_literal,1440 .tag = .string_literal,
1441 .main_token = std_tok,1441 .main_token = std_tok,
1442 .data = .{1442 .data = undefined,
1443 .lhs = undefined,
1444 .rhs = undefined,
1445 },
1446 });1443 });
1447 _ = try c.addToken(.r_paren, ")");1444 _ = try c.addToken(.r_paren, ")");
14481445
...@@ -1498,21 +1495,23 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {...@@ -1498,21 +1495,23 @@ fn renderCall(c: *Context, lhs: NodeIndex, args: []const Node) !NodeIndex {
1498 });1495 });
1499 },1496 },
1500 else => blk: {1497 else => blk: {
1501 const start = @intCast(u32, c.extra_data.items.len);1498 var rendered = try c.gpa.alloc(NodeIndex, args.len);
1502 const end = @intCast(u32, start + args.len);1499 defer c.gpa.free(rendered);
1503 try c.extra_data.ensureCapacity(c.gpa, end + 2); // + 2 for span start + end1500
1504 for (args) |arg, i| {1501 for (args) |arg, i| {
1505 if (i != 0) _ = try c.addToken(.comma, ",");1502 if (i != 0) _ = try c.addToken(.comma, ",");
1506 c.extra_data.appendAssumeCapacity(try renderNode(c, arg));1503 rendered[i] = try renderNode(c, arg);
1507 }1504 }
1508 c.extra_data.appendAssumeCapacity(start);1505 const span = try c.listToSpan(rendered);
1509 c.extra_data.appendAssumeCapacity(end);
1510 break :blk try c.addNode(.{1506 break :blk try c.addNode(.{
1511 .tag = .call_comma,1507 .tag = .call,
1512 .main_token = lparen,1508 .main_token = lparen,
1513 .data = .{1509 .data = .{
1514 .lhs = lhs,1510 .lhs = lhs,
1515 .rhs = end + 2,1511 .rhs = try c.addExtra(std.zig.ast.Node.SubRange{
1512 .start = span.start,
1513 .end = span.end,
1514 }),
1516 },1515 },
1517 });1516 });
1518 },1517 },
...@@ -1653,20 +1652,20 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -1653,20 +1652,20 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
16531652
1654 var span: NodeSubRange = undefined;1653 var span: NodeSubRange = undefined;
1655 if (payload.params.len > 1) {1654 if (payload.params.len > 1) {
1656 var params = std.ArrayList(NodeIndex).init(c.gpa);1655 var params = try c.gpa.alloc(NodeIndex, payload.params.len);
1657 defer params.deinit();1656 defer c.gpa.free(params);
16581657
1659 try params.append(first);1658 params[0] = first;
1660 for (payload.params[1..]) |param| {1659 for (payload.params[1..]) |param, i| {
1661 _ = try c.addToken(.comma, ",");1660 _ = try c.addToken(.comma, ",");
1662 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");1661 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
1663 if (param.name) |some| {1662 if (param.name) |some| {
1664 _ = try c.addIdentifier(some);1663 _ = try c.addIdentifier(some);
1665 _ = try c.addToken(.colon, ":");1664 _ = try c.addToken(.colon, ":");
1666 }1665 }
1667 try params.append(try renderNode(c, param.type));1666 params[i + 1] = try renderNode(c, param.type);
1668 }1667 }
1669 span = try c.listToSpan(params.items);1668 span = try c.listToSpan(params);
1670 }1669 }
1671 if (payload.is_var_args) {1670 if (payload.is_var_args) {
1672 if (payload.params.len != 0) _ = try c.addToken(.comma, ",");1671 if (payload.params.len != 0) _ = try c.addToken(.comma, ",");
...@@ -1674,8 +1673,6 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -1674,8 +1673,6 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
1674 }1673 }
1675 _ = try c.addToken(.r_paren, ")");1674 _ = try c.addToken(.r_paren, ")");
16761675
1677 const return_type_expr = try renderNode(c, payload.return_type);
1678
1679 const align_expr = if (payload.alignment) |some| blk: {1676 const align_expr = if (payload.alignment) |some| blk: {
1680 _ = try c.addToken(.keyword_align, "align");1677 _ = try c.addToken(.keyword_align, "align");
1681 _ = try c.addToken(.l_paren, "(");1678 _ = try c.addToken(.l_paren, "(");
...@@ -1701,18 +1698,20 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -1701,18 +1698,20 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
1701 } else 0;1698 } else 0;
17021699
1703 const callconv_expr = if (payload.explicit_callconv) |some| blk: {1700 const callconv_expr = if (payload.explicit_callconv) |some| blk: {
1704 _ = try c.addToken(.keyword_linksection, "callconv");1701 _ = try c.addToken(.keyword_callconv, "callconv");
1705 _ = try c.addToken(.l_paren, "(");1702 _ = try c.addToken(.l_paren, "(");
1706 _ = try c.addToken(.period, ".");1703 _ = try c.addToken(.period, ".");
1707 const res = try c.addNode(.{1704 const res = try c.addNode(.{
1708 .tag = .enum_literal,1705 .tag = .enum_literal,
1709 .main_token = try c.addTokenFmt(.string_literal, "{}", .{some}),1706 .main_token = try c.addTokenFmt(.identifier, "{}", .{some}),
1710 .data = .{ .lhs = undefined, .rhs = undefined },1707 .data = .{ .lhs = undefined, .rhs = undefined },
1711 });1708 });
1712 _ = try c.addToken(.r_paren, ")");1709 _ = try c.addToken(.r_paren, ")");
1713 break :blk res;1710 break :blk res;
1714 } else 0;1711 } else 0;
17151712
1713 const return_type_expr = try renderNode(c, payload.return_type);
1714
1716 const fn_proto = try blk: {1715 const fn_proto = try blk: {
1717 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {1716 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {
1718 if (payload.params.len < 2)1717 if (payload.params.len < 2)
...@@ -1784,3 +1783,94 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {...@@ -1784,3 +1783,94 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
1784 },1783 },
1785 });1784 });
1786}1785}
1786
1787fn renderMacroFunc(c: *Context, node: Node) !NodeIndex {
1788 const payload = node.castTag(.pub_inline_fn).?.data;
1789 _ = try c.addToken(.keyword_pub, "pub");
1790 const fn_token = try c.addToken(.keyword_fn, "fn");
1791 _ = try c.addIdentifier(payload.name);
1792
1793 _ = try c.addToken(.l_paren, "(");
1794 const first = if (payload.params.len != 0) blk: {
1795 const param = payload.params[0];
1796 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
1797 if (param.name) |some| {
1798 _ = try c.addIdentifier(some);
1799 _ = try c.addToken(.colon, ":");
1800 }
1801 break :blk try renderNode(c, param.type);
1802 } else 0;
1803
1804 var span: NodeSubRange = undefined;
1805 if (payload.params.len > 1) {
1806 var params = try c.gpa.alloc(NodeIndex, payload.params.len);
1807 defer c.gpa.free(params);
1808
1809 params[0] = first;
1810 for (payload.params[1..]) |param, i| {
1811 _ = try c.addToken(.comma, ",");
1812 if (param.is_noalias) _ = try c.addToken(.keyword_noalias, "noalias");
1813 if (param.name) |some| {
1814 _ = try c.addIdentifier(some);
1815 _ = try c.addToken(.colon, ":");
1816 }
1817 params[i + 1] = try renderNode(c, param.type);
1818 }
1819 span = try c.listToSpan(params);
1820 }
1821 _ = try c.addToken(.r_paren, ")");
1822
1823 const callconv_expr = blk: {
1824 _ = try c.addToken(.keyword_callconv, "callconv");
1825 _ = try c.addToken(.l_paren, "(");
1826 _ = try c.addToken(.period, ".");
1827 const res = try c.addNode(.{
1828 .tag = .enum_literal,
1829 .main_token = try c.addToken(.identifier, "Inline"),
1830 .data = .{ .lhs = undefined, .rhs = undefined },
1831 });
1832 _ = try c.addToken(.r_paren, ")");
1833 break :blk res;
1834 };
1835 const return_type_expr = try renderNode(c, payload.return_type);
1836
1837 const fn_proto = try blk: {
1838 if (payload.params.len < 2)
1839 break :blk c.addNode(.{
1840 .tag = .fn_proto_one,
1841 .main_token = fn_token,
1842 .data = .{
1843 .lhs = try c.addExtra(std.zig.ast.Node.FnProtoOne{
1844 .param = first,
1845 .align_expr = 0,
1846 .section_expr = 0,
1847 .callconv_expr = callconv_expr,
1848 }),
1849 .rhs = return_type_expr,
1850 },
1851 })
1852 else
1853 break :blk c.addNode(.{
1854 .tag = .fn_proto,
1855 .main_token = fn_token,
1856 .data = .{
1857 .lhs = try c.addExtra(std.zig.ast.Node.FnProto{
1858 .params_start = span.start,
1859 .params_end = span.end,
1860 .align_expr = 0,
1861 .section_expr = 0,
1862 .callconv_expr = callconv_expr,
1863 }),
1864 .rhs = return_type_expr,
1865 },
1866 });
1867 };
1868 return c.addNode(.{
1869 .tag = .fn_decl,
1870 .main_token = fn_token,
1871 .data = .{
1872 .lhs = fn_proto,
1873 .rhs = try renderNode(c, payload.body),
1874 },
1875 });
1876}