Commit 15603f403c
Changed files (3)
lib
std
lib/std/zig/ast.zig
@@ -2642,20 +2642,29 @@ pub const Node = struct {
@"return",
/// `fn(a: lhs) rhs`. lhs can be omitted.
/// anytype and ... parameters are omitted from the AST tree.
+ /// main_token is the `fn` keyword.
+ /// extern function declarations use this tag.
fn_proto_simple,
/// `fn(a: b, c: d) rhs`. `sub_range_list[lhs]`.
/// anytype and ... parameters are omitted from the AST tree.
+ /// main_token is the `fn` keyword.
+ /// extern function declarations use this tag.
fn_proto_multi,
/// `fn(a: b) rhs linksection(e) callconv(f)`. `FnProtoOne[lhs]`.
/// zero or one parameters.
/// anytype and ... parameters are omitted from the AST tree.
+ /// main_token is the `fn` keyword.
+ /// extern function declarations use this tag.
fn_proto_one,
/// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.
/// anytype and ... parameters are omitted from the AST tree.
+ /// main_token is the `fn` keyword.
+ /// extern function declarations use this tag.
fn_proto,
/// lhs is the fn_proto.
- /// rhs is the function body block if non-zero.
- /// if rhs is zero, the function decl has no body (e.g. an extern function)
+ /// rhs is the function body block.
+ /// Note that extern function declarations use the fn_proto tags rather
+ /// than this one.
fn_decl,
/// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
anyframe_type,
lib/std/zig/parse.zig
@@ -542,15 +542,8 @@ const Parser = struct {
if (fn_proto != 0) {
switch (p.token_tags[p.tok_i]) {
.semicolon => {
- const semicolon_token = p.nextToken();
- return p.addNode(.{
- .tag = .fn_decl,
- .main_token = p.nodes.items(.main_token)[fn_proto],
- .data = .{
- .lhs = fn_proto,
- .rhs = 0,
- },
- });
+ p.tok_i += 1;
+ return fn_proto;
},
.l_brace => {
const body_block = try p.parseBlock();
lib/std/zig/render.zig
@@ -81,19 +81,39 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
while (i < fn_token) : (i += 1) {
try renderToken(ais, tree, i, .space);
}
- if (datas[decl].rhs != 0) {
- try renderExpression(ais, tree, fn_proto, .space);
- return renderExpression(ais, tree, datas[decl].rhs, space);
- } else {
- try renderExpression(ais, tree, fn_proto, .none);
- return renderToken(ais, tree, tree.lastToken(fn_proto) + 1, space); // semicolon
- }
+ assert(datas[decl].rhs != 0);
+ try renderExpression(ais, tree, fn_proto, .space);
+ return renderExpression(ais, tree, datas[decl].rhs, space);
},
.fn_proto_simple,
.fn_proto_multi,
.fn_proto_one,
.fn_proto,
=> {
+ // Extern function prototypes are parsed as these tags.
+ // Go back to the first token we should render here.
+ const fn_token = main_tokens[decl];
+ var i = fn_token;
+ while (i > 0) {
+ i -= 1;
+ switch (token_tags[i]) {
+ .keyword_extern,
+ .keyword_export,
+ .keyword_pub,
+ .string_literal,
+ .keyword_inline,
+ .keyword_noinline,
+ => continue,
+
+ else => {
+ i += 1;
+ break;
+ },
+ }
+ }
+ while (i < fn_token) : (i += 1) {
+ try renderToken(ais, tree, i, .space);
+ }
try renderExpression(ais, tree, decl, .none);
return renderToken(ais, tree, tree.lastToken(decl) + 1, space); // semicolon
},