authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-21 16:01:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-21 16:01:22-07:00
log15603f403c9ca91f7530798a5a7751cace284a28
tree284e39036ac551ecc35316514094784e547be70d
parent88d0e77b9747152a923e4a4479988924de0fe26f

AST: use fn_proto not fn_decl for extern decls

saves a few bytes per extern function declaration

3 files changed, 40 insertions(+), 18 deletions(-)

lib/std/zig/ast.zig+11-2
...@@ -2642,20 +2642,29 @@ pub const Node = struct {...@@ -2642,20 +2642,29 @@ pub const Node = struct {
2642 @"return",2642 @"return",
2643 /// `fn(a: lhs) rhs`. lhs can be omitted.2643 /// `fn(a: lhs) rhs`. lhs can be omitted.
2644 /// anytype and ... parameters are omitted from the AST tree.2644 /// anytype and ... parameters are omitted from the AST tree.
2645 /// main_token is the `fn` keyword.
2646 /// extern function declarations use this tag.
2645 fn_proto_simple,2647 fn_proto_simple,
2646 /// `fn(a: b, c: d) rhs`. `sub_range_list[lhs]`.2648 /// `fn(a: b, c: d) rhs`. `sub_range_list[lhs]`.
2647 /// anytype and ... parameters are omitted from the AST tree.2649 /// anytype and ... parameters are omitted from the AST tree.
2650 /// main_token is the `fn` keyword.
2651 /// extern function declarations use this tag.
2648 fn_proto_multi,2652 fn_proto_multi,
2649 /// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`.2653 /// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`.
2650 /// zero or one parameters.2654 /// zero or one parameters.
2651 /// anytype and ... parameters are omitted from the AST tree.2655 /// anytype and ... parameters are omitted from the AST tree.
2656 /// main_token is the `fn` keyword.
2657 /// extern function declarations use this tag.
2652 fn_proto_one,2658 fn_proto_one,
2653 /// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.2659 /// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.
2654 /// anytype and ... parameters are omitted from the AST tree.2660 /// anytype and ... parameters are omitted from the AST tree.
2661 /// main_token is the `fn` keyword.
2662 /// extern function declarations use this tag.
2655 fn_proto,2663 fn_proto,
2656 /// lhs is the fn_proto.2664 /// lhs is the fn_proto.
2657 /// rhs is the function body block if non-zero.2665 /// rhs is the function body block.
2658 /// if rhs is zero, the function decl has no body (e.g. an extern function)2666 /// Note that extern function declarations use the fn_proto tags rather
2667 /// than this one.
2659 fn_decl,2668 fn_decl,
2660 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.2669 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
2661 anyframe_type,2670 anyframe_type,
lib/std/zig/parse.zig+2-9
...@@ -542,15 +542,8 @@ const Parser = struct {...@@ -542,15 +542,8 @@ const Parser = struct {
542 if (fn_proto != 0) {542 if (fn_proto != 0) {
543 switch (p.token_tags[p.tok_i]) {543 switch (p.token_tags[p.tok_i]) {
544 .semicolon => {544 .semicolon => {
545 const semicolon_token = p.nextToken();545 p.tok_i += 1;
546 return p.addNode(.{546 return fn_proto;
547 .tag = .fn_decl,
548 .main_token = p.nodes.items(.main_token)[fn_proto],
549 .data = .{
550 .lhs = fn_proto,
551 .rhs = 0,
552 },
553 });
554 },547 },
555 .l_brace => {548 .l_brace => {
556 const body_block = try p.parseBlock();549 const body_block = try p.parseBlock();
lib/std/zig/render.zig+27-7
...@@ -81,19 +81,39 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E...@@ -81,19 +81,39 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
81 while (i < fn_token) : (i += 1) {81 while (i < fn_token) : (i += 1) {
82 try renderToken(ais, tree, i, .space);82 try renderToken(ais, tree, i, .space);
83 }83 }
84 if (datas[decl].rhs != 0) {84 assert(datas[decl].rhs != 0);
85 try renderExpression(ais, tree, fn_proto, .space);85 try renderExpression(ais, tree, fn_proto, .space);
86 return renderExpression(ais, tree, datas[decl].rhs, space);86 return renderExpression(ais, tree, datas[decl].rhs, space);
87 } else {
88 try renderExpression(ais, tree, fn_proto, .none);
89 return renderToken(ais, tree, tree.lastToken(fn_proto) + 1, space); // semicolon
90 }
91 },87 },
92 .fn_proto_simple,88 .fn_proto_simple,
93 .fn_proto_multi,89 .fn_proto_multi,
94 .fn_proto_one,90 .fn_proto_one,
95 .fn_proto,91 .fn_proto,
96 => {92 => {
93 // Extern function prototypes are parsed as these tags.
94 // Go back to the first token we should render here.
95 const fn_token = main_tokens[decl];
96 var i = fn_token;
97 while (i > 0) {
98 i -= 1;
99 switch (token_tags[i]) {
100 .keyword_extern,
101 .keyword_export,
102 .keyword_pub,
103 .string_literal,
104 .keyword_inline,
105 .keyword_noinline,
106 => continue,
107
108 else => {
109 i += 1;
110 break;
111 },
112 }
113 }
114 while (i < fn_token) : (i += 1) {
115 try renderToken(ais, tree, i, .space);
116 }
97 try renderExpression(ais, tree, decl, .none);117 try renderExpression(ais, tree, decl, .none);
98 return renderToken(ais, tree, tree.lastToken(decl) + 1, space); // semicolon118 return renderToken(ais, tree, tree.lastToken(decl) + 1, space); // semicolon
99 },119 },