authorgravatar for me@tadeo.caTadeo Kondrak <me@tadeo.ca> 2020-05-04 09:06:20-06:00
committergravatar for me@tadeo.caTadeo Kondrak <me@tadeo.ca> 2020-05-05 09:37:28-06:00
log7ada59f873738931b4d162372dff0a33442112b6
treed49d68fb89c784186c069584b91fb6e2a841dba2
parente6955688ac2255d3813e8d2994b6661bc651369b
signature Commit is signed but in an unrecognized format.

remove nakedcc/stdcallcc/async fn/extern fn fnproto


11 files changed, 9 insertions(+), 165 deletions(-)

doc/docgen.zig-2
...@@ -800,7 +800,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok...@@ -800,7 +800,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
800 .Keyword_for,800 .Keyword_for,
801 .Keyword_if,801 .Keyword_if,
802 .Keyword_inline,802 .Keyword_inline,
803 .Keyword_nakedcc,
804 .Keyword_noalias,803 .Keyword_noalias,
805 .Keyword_noinline,804 .Keyword_noinline,
806 .Keyword_nosuspend,805 .Keyword_nosuspend,
...@@ -813,7 +812,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok...@@ -813,7 +812,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
813 .Keyword_return,812 .Keyword_return,
814 .Keyword_linksection,813 .Keyword_linksection,
815 .Keyword_callconv,814 .Keyword_callconv,
816 .Keyword_stdcallcc,
817 .Keyword_struct,815 .Keyword_struct,
818 .Keyword_suspend,816 .Keyword_suspend,
819 .Keyword_switch,817 .Keyword_switch,
doc/langref.html.in+1-6
...@@ -10088,7 +10088,7 @@ TopLevelDecl...@@ -10088,7 +10088,7 @@ TopLevelDecl
10088 / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl10088 / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
10089 / KEYWORD_usingnamespace Expr SEMICOLON10089 / KEYWORD_usingnamespace Expr SEMICOLON
1009010090
10091FnProto &lt;- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)10091FnProto &lt;- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
1009210092
10093VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON10093VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
1009410094
...@@ -10255,11 +10255,6 @@ WhileContinueExpr &lt;- COLON LPAREN AssignExpr RPAREN...@@ -10255,11 +10255,6 @@ WhileContinueExpr &lt;- COLON LPAREN AssignExpr RPAREN
1025510255
10256LinkSection &lt;- KEYWORD_linksection LPAREN Expr RPAREN10256LinkSection &lt;- KEYWORD_linksection LPAREN Expr RPAREN
1025710257
10258# Fn specific
10259FnCC
10260 &lt;- KEYWORD_extern
10261 / KEYWORD_async
10262
10263ParamDecl &lt;- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType10258ParamDecl &lt;- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
1026410259
10265ParamType10260ParamType
lib/std/zig/ast.zig-2
...@@ -875,7 +875,6 @@ pub const Node = struct {...@@ -875,7 +875,6 @@ pub const Node = struct {
875 return_type: ReturnType,875 return_type: ReturnType,
876 var_args_token: ?TokenIndex,876 var_args_token: ?TokenIndex,
877 extern_export_inline_token: ?TokenIndex,877 extern_export_inline_token: ?TokenIndex,
878 cc_token: ?TokenIndex,
879 body_node: ?*Node,878 body_node: ?*Node,
880 lib_name: ?*Node, // populated if this is an extern declaration879 lib_name: ?*Node, // populated if this is an extern declaration
881 align_expr: ?*Node, // populated if align(A) is present880 align_expr: ?*Node, // populated if align(A) is present
...@@ -929,7 +928,6 @@ pub const Node = struct {...@@ -929,7 +928,6 @@ pub const Node = struct {
929 if (self.visib_token) |visib_token| return visib_token;928 if (self.visib_token) |visib_token| return visib_token;
930 if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;929 if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
931 assert(self.lib_name == null);930 assert(self.lib_name == null);
932 if (self.cc_token) |cc_token| return cc_token;
933 return self.fn_token;931 return self.fn_token;
934 }932 }
935933
lib/std/zig/parse.zig+2-51
...@@ -335,22 +335,9 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -335,22 +335,9 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
335 return use_node;335 return use_node;
336}336}
337337
338/// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)338/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
339fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {339fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
340 const cc = parseFnCC(arena, it, tree);340 const fn_token = eatToken(it, .Keyword_fn) orelse return null;
341 const fn_token = eatToken(it, .Keyword_fn) orelse {
342 if (cc) |fnCC| {
343 if (fnCC == .Extern) {
344 putBackToken(it, fnCC.Extern); // 'extern' is also used in ContainerDecl
345 } else {
346 try tree.errors.push(.{
347 .ExpectedToken = .{ .token = it.index, .expected_id = .Keyword_fn },
348 });
349 return error.ParseError;
350 }
351 }
352 return null;
353 };
354 const name_token = eatToken(it, .Identifier);341 const name_token = eatToken(it, .Identifier);
355 const lparen = try expectToken(it, tree, .LParen);342 const lparen = try expectToken(it, tree, .LParen);
356 const params = try parseParamDeclList(arena, it, tree);343 const params = try parseParamDeclList(arena, it, tree);
...@@ -389,7 +376,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -389,7 +376,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
389 .return_type = return_type,376 .return_type = return_type,
390 .var_args_token = var_args_token,377 .var_args_token = var_args_token,
391 .extern_export_inline_token = null,378 .extern_export_inline_token = null,
392 .cc_token = null,
393 .body_node = null,379 .body_node = null,
394 .lib_name = null,380 .lib_name = null,
395 .align_expr = align_expr,381 .align_expr = align_expr,
...@@ -397,13 +383,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -397,13 +383,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
397 .callconv_expr = callconv_expr,383 .callconv_expr = callconv_expr,
398 };384 };
399385
400 if (cc) |kind| {
401 switch (kind) {
402 .CC => |token| fn_proto_node.cc_token = token,
403 .Extern => |token| fn_proto_node.extern_export_inline_token = token,
404 }
405 }
406
407 return &fn_proto_node.base;386 return &fn_proto_node.base;
408}387}
409388
...@@ -1196,16 +1175,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1196,16 +1175,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1196 const maybe_async = eatToken(it, .Keyword_async);1175 const maybe_async = eatToken(it, .Keyword_async);
1197 if (maybe_async) |async_token| {1176 if (maybe_async) |async_token| {
1198 const token_fn = eatToken(it, .Keyword_fn);1177 const token_fn = eatToken(it, .Keyword_fn);
1199 if (token_fn != null) {
1200 // HACK: If we see the keyword `fn`, then we assume that
1201 // we are parsing an async fn proto, and not a call.
1202 // We therefore put back all tokens consumed by the async
1203 // prefix...
1204 putBackToken(it, token_fn.?);
1205 putBackToken(it, async_token);
1206 return parsePrimaryTypeExpr(arena, it, tree);
1207 }
1208 // TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr
1209 var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, .{1178 var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, .{
1210 .ExpectedPrimaryTypeExpr = .{ .token = it.index },1179 .ExpectedPrimaryTypeExpr = .{ .token = it.index },
1211 });1180 });
...@@ -1778,24 +1747,6 @@ fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1778,24 +1747,6 @@ fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1778 return expr_node;1747 return expr_node;
1779}1748}
17801749
1781/// FnCC
1782/// <- KEYWORD_nakedcc
1783/// / KEYWORD_stdcallcc
1784/// / KEYWORD_extern
1785/// / KEYWORD_async
1786fn parseFnCC(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?FnCC {
1787 if (eatToken(it, .Keyword_nakedcc)) |token| return FnCC{ .CC = token };
1788 if (eatToken(it, .Keyword_stdcallcc)) |token| return FnCC{ .CC = token };
1789 if (eatToken(it, .Keyword_extern)) |token| return FnCC{ .Extern = token };
1790 if (eatToken(it, .Keyword_async)) |token| return FnCC{ .CC = token };
1791 return null;
1792}
1793
1794const FnCC = union(enum) {
1795 CC: TokenIndex,
1796 Extern: TokenIndex,
1797};
1798
1799/// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType1750/// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
1800fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {1751fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1801 const doc_comments = try parseDocComment(arena, it, tree);1752 const doc_comments = try parseDocComment(arena, it, tree);
lib/std/zig/parser_test.zig-16
...@@ -123,22 +123,6 @@ test "zig fmt: trailing comma in fn parameter list" {...@@ -123,22 +123,6 @@ test "zig fmt: trailing comma in fn parameter list" {
123 );123 );
124}124}
125125
126// TODO: Remove nakedcc/stdcallcc once zig 0.6.0 is released. See https://github.com/ziglang/zig/pull/3977
127test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {
128 try testTransform(
129 \\nakedcc fn foo1() void {}
130 \\stdcallcc fn foo2() void {}
131 \\extern fn foo3() void {}
132 \\extern "mylib" fn foo4() void {}
133 ,
134 \\fn foo1() callconv(.Naked) void {}
135 \\fn foo2() callconv(.Stdcall) void {}
136 \\fn foo3() callconv(.C) void {}
137 \\fn foo4() callconv(.C) void {}
138 \\
139 );
140}
141
142test "zig fmt: comptime struct field" {126test "zig fmt: comptime struct field" {
143 try testCanonical(127 try testCanonical(
144 \\const Foo = struct {128 \\const Foo = struct {
lib/std/zig/render.zig+1-23
...@@ -1413,32 +1413,14 @@ fn renderExpression(...@@ -1413,32 +1413,14 @@ fn renderExpression(
1413 try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub1413 try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub
1414 }1414 }
14151415
1416 // Some extra machinery is needed to rewrite the old-style cc
1417 // notation to the new callconv one
1418 var cc_rewrite_str: ?[*:0]const u8 = null;
1419 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {1416 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
1420 const tok = tree.tokens.at(extern_export_inline_token);1417 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
1421 if (tok.id != .Keyword_extern or fn_proto.body_node == null) {
1422 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
1423 } else {
1424 cc_rewrite_str = ".C";
1425 fn_proto.lib_name = null;
1426 }
1427 }1418 }
14281419
1429 if (fn_proto.lib_name) |lib_name| {1420 if (fn_proto.lib_name) |lib_name| {
1430 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);1421 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
1431 }1422 }
14321423
1433 if (fn_proto.cc_token) |cc_token| {
1434 var str = tree.tokenSlicePtr(tree.tokens.at(cc_token));
1435 if (mem.eql(u8, str, "stdcallcc")) {
1436 cc_rewrite_str = ".Stdcall";
1437 } else if (mem.eql(u8, str, "nakedcc")) {
1438 cc_rewrite_str = ".Naked";
1439 } else try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
1440 }
1441
1442 const lparen = if (fn_proto.name_token) |name_token| blk: {1424 const lparen = if (fn_proto.name_token) |name_token| blk: {
1443 try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn1425 try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
1444 try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name1426 try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name
...@@ -1528,10 +1510,6 @@ fn renderExpression(...@@ -1528,10 +1510,6 @@ fn renderExpression(
1528 try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (1510 try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (
1529 try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);1511 try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);
1530 try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )1512 try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )
1531 } else if (cc_rewrite_str) |str| {
1532 try stream.writeAll("callconv(");
1533 try stream.writeAll(mem.spanZ(str));
1534 try stream.writeAll(") ");
1535 }1513 }
15361514
1537 switch (fn_proto.return_type) {1515 switch (fn_proto.return_type) {
lib/std/zig/tokenizer.zig-6
...@@ -47,7 +47,6 @@ pub const Token = struct {...@@ -47,7 +47,6 @@ pub const Token = struct {
47 Keyword.init("for", .Keyword_for),47 Keyword.init("for", .Keyword_for),
48 Keyword.init("if", .Keyword_if),48 Keyword.init("if", .Keyword_if),
49 Keyword.init("inline", .Keyword_inline),49 Keyword.init("inline", .Keyword_inline),
50 Keyword.init("nakedcc", .Keyword_nakedcc),
51 Keyword.init("noalias", .Keyword_noalias),50 Keyword.init("noalias", .Keyword_noalias),
52 Keyword.init("noasync", .Keyword_nosuspend), // TODO: remove this51 Keyword.init("noasync", .Keyword_nosuspend), // TODO: remove this
53 Keyword.init("noinline", .Keyword_noinline),52 Keyword.init("noinline", .Keyword_noinline),
...@@ -60,7 +59,6 @@ pub const Token = struct {...@@ -60,7 +59,6 @@ pub const Token = struct {
60 Keyword.init("resume", .Keyword_resume),59 Keyword.init("resume", .Keyword_resume),
61 Keyword.init("return", .Keyword_return),60 Keyword.init("return", .Keyword_return),
62 Keyword.init("linksection", .Keyword_linksection),61 Keyword.init("linksection", .Keyword_linksection),
63 Keyword.init("stdcallcc", .Keyword_stdcallcc),
64 Keyword.init("struct", .Keyword_struct),62 Keyword.init("struct", .Keyword_struct),
65 Keyword.init("suspend", .Keyword_suspend),63 Keyword.init("suspend", .Keyword_suspend),
66 Keyword.init("switch", .Keyword_switch),64 Keyword.init("switch", .Keyword_switch),
...@@ -181,7 +179,6 @@ pub const Token = struct {...@@ -181,7 +179,6 @@ pub const Token = struct {
181 Keyword_for,179 Keyword_for,
182 Keyword_if,180 Keyword_if,
183 Keyword_inline,181 Keyword_inline,
184 Keyword_nakedcc,
185 Keyword_noalias,182 Keyword_noalias,
186 Keyword_noinline,183 Keyword_noinline,
187 Keyword_nosuspend,184 Keyword_nosuspend,
...@@ -194,7 +191,6 @@ pub const Token = struct {...@@ -194,7 +191,6 @@ pub const Token = struct {
194 Keyword_resume,191 Keyword_resume,
195 Keyword_return,192 Keyword_return,
196 Keyword_linksection,193 Keyword_linksection,
197 Keyword_stdcallcc,
198 Keyword_struct,194 Keyword_struct,
199 Keyword_suspend,195 Keyword_suspend,
200 Keyword_switch,196 Keyword_switch,
...@@ -306,7 +302,6 @@ pub const Token = struct {...@@ -306,7 +302,6 @@ pub const Token = struct {
306 .Keyword_for => "for",302 .Keyword_for => "for",
307 .Keyword_if => "if",303 .Keyword_if => "if",
308 .Keyword_inline => "inline",304 .Keyword_inline => "inline",
309 .Keyword_nakedcc => "nakedcc",
310 .Keyword_noalias => "noalias",305 .Keyword_noalias => "noalias",
311 .Keyword_noinline => "noinline",306 .Keyword_noinline => "noinline",
312 .Keyword_nosuspend => "nosuspend",307 .Keyword_nosuspend => "nosuspend",
...@@ -318,7 +313,6 @@ pub const Token = struct {...@@ -318,7 +313,6 @@ pub const Token = struct {
318 .Keyword_resume => "resume",313 .Keyword_resume => "resume",
319 .Keyword_return => "return",314 .Keyword_return => "return",
320 .Keyword_linksection => "linksection",315 .Keyword_linksection => "linksection",
321 .Keyword_stdcallcc => "stdcallcc",
322 .Keyword_struct => "struct",316 .Keyword_struct => "struct",
323 .Keyword_suspend => "suspend",317 .Keyword_suspend => "suspend",
324 .Keyword_switch => "switch",318 .Keyword_switch => "switch",
src-self-hosted/translate_c.zig-3
...@@ -4094,7 +4094,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a...@@ -4094,7 +4094,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
4094 .return_type = proto_alias.return_type,4094 .return_type = proto_alias.return_type,
4095 .var_args_token = null,4095 .var_args_token = null,
4096 .extern_export_inline_token = inline_tok,4096 .extern_export_inline_token = inline_tok,
4097 .cc_token = null,
4098 .body_node = null,4097 .body_node = null,
4099 .lib_name = null,4098 .lib_name = null,
4100 .align_expr = null,4099 .align_expr = null,
...@@ -4753,7 +4752,6 @@ fn finishTransFnProto(...@@ -4753,7 +4752,6 @@ fn finishTransFnProto(
4753 .return_type = .{ .Explicit = return_type_node },4752 .return_type = .{ .Explicit = return_type_node },
4754 .var_args_token = null, // TODO this field is broken in the AST data model4753 .var_args_token = null, // TODO this field is broken in the AST data model
4755 .extern_export_inline_token = extern_export_inline_tok,4754 .extern_export_inline_token = extern_export_inline_tok,
4756 .cc_token = null,
4757 .body_node = null,4755 .body_node = null,
4758 .lib_name = null,4756 .lib_name = null,
4759 .align_expr = align_expr,4757 .align_expr = align_expr,
...@@ -5119,7 +5117,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5119,7 +5117,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5119 .return_type = .{ .Explicit = &type_of.base },5117 .return_type = .{ .Explicit = &type_of.base },
5120 .doc_comments = null,5118 .doc_comments = null,
5121 .var_args_token = null,5119 .var_args_token = null,
5122 .cc_token = null,
5123 .body_node = null,5120 .body_node = null,
5124 .lib_name = null,5121 .lib_name = null,
5125 .align_expr = null,5122 .align_expr = null,
src/all_types.hpp-1
...@@ -718,7 +718,6 @@ struct AstNodeFnProto {...@@ -718,7 +718,6 @@ struct AstNodeFnProto {
718 Buf doc_comments;718 Buf doc_comments;
719719
720 FnInline fn_inline;720 FnInline fn_inline;
721 bool is_async;
722721
723 VisibMod visib_mod;722 VisibMod visib_mod;
724 bool auto_err_set;723 bool auto_err_set;
src/analyze.cpp-2
...@@ -1528,8 +1528,6 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1528,8 +1528,6 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1528}1528}
15291529
1530CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {1530CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {
1531 if (fn_proto->is_async)
1532 return CallingConventionAsync;
1533 // Compatible with the C ABI1531 // Compatible with the C ABI
1534 if (fn_proto->is_extern || fn_proto->is_export)1532 if (fn_proto->is_extern || fn_proto->is_export)
1535 return CallingConventionC;1533 return CallingConventionC;
src/parser.cpp+5-53
...@@ -93,7 +93,6 @@ static AstNode *ast_parse_field_init(ParseContext *pc);...@@ -93,7 +93,6 @@ static AstNode *ast_parse_field_init(ParseContext *pc);
93static AstNode *ast_parse_while_continue_expr(ParseContext *pc);93static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
94static AstNode *ast_parse_link_section(ParseContext *pc);94static AstNode *ast_parse_link_section(ParseContext *pc);
95static AstNode *ast_parse_callconv(ParseContext *pc);95static AstNode *ast_parse_callconv(ParseContext *pc);
96static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc);
97static AstNode *ast_parse_param_decl(ParseContext *pc);96static AstNode *ast_parse_param_decl(ParseContext *pc);
98static AstNode *ast_parse_param_type(ParseContext *pc);97static AstNode *ast_parse_param_type(ParseContext *pc);
99static AstNode *ast_parse_if_prefix(ParseContext *pc);98static AstNode *ast_parse_if_prefix(ParseContext *pc);
...@@ -707,7 +706,6 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -707,7 +706,6 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
707 fn_proto->column = first->start_column;706 fn_proto->column = first->start_column;
708 fn_proto->data.fn_proto.visib_mod = visib_mod;707 fn_proto->data.fn_proto.visib_mod = visib_mod;
709 fn_proto->data.fn_proto.doc_comments = *doc_comments;708 fn_proto->data.fn_proto.doc_comments = *doc_comments;
710 // ast_parse_fn_cc may set it
711 if (!fn_proto->data.fn_proto.is_extern)709 if (!fn_proto->data.fn_proto.is_extern)
712 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;710 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;
713 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;711 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;
...@@ -788,29 +786,11 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -788,29 +786,11 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
788 return nullptr;786 return nullptr;
789}787}
790788
791// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)789// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
792static AstNode *ast_parse_fn_proto(ParseContext *pc) {790static AstNode *ast_parse_fn_proto(ParseContext *pc) {
793 Token *first = peek_token(pc);791 Token *first = eat_token_if(pc, TokenIdKeywordFn);
794 AstNodeFnProto fn_cc;792 if (first == nullptr) {
795 Token *fn;793 return nullptr;
796 if (ast_parse_fn_cc(pc).unwrap(&fn_cc)) {
797 // The extern keyword for fn CC is also used for container decls.
798 // We therefore put it back, as allow container decl to consume it
799 // later.
800 if (fn_cc.is_extern) {
801 fn = eat_token_if(pc, TokenIdKeywordFn);
802 if (fn == nullptr) {
803 put_back_token(pc);
804 return nullptr;
805 }
806 } else {
807 fn = expect_token(pc, TokenIdKeywordFn);
808 }
809 } else {
810 fn_cc = {};
811 fn = eat_token_if(pc, TokenIdKeywordFn);
812 if (fn == nullptr)
813 return nullptr;
814 }794 }
815795
816 Token *identifier = eat_token_if(pc, TokenIdSymbol);796 Token *identifier = eat_token_if(pc, TokenIdSymbol);
...@@ -830,7 +810,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {...@@ -830,7 +810,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
830 }810 }
831811
832 AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);812 AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);
833 res->data.fn_proto = fn_cc;813 res->data.fn_proto = {};
834 res->data.fn_proto.name = token_buf(identifier);814 res->data.fn_proto.name = token_buf(identifier);
835 res->data.fn_proto.params = params;815 res->data.fn_proto.params = params;
836 res->data.fn_proto.align_expr = align_expr;816 res->data.fn_proto.align_expr = align_expr;
...@@ -1524,17 +1504,6 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {...@@ -1524,17 +1504,6 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
1524static AstNode *ast_parse_suffix_expr(ParseContext *pc) {1504static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
1525 Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);1505 Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
1526 if (async_token) {1506 if (async_token) {
1527 if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
1528 // HACK: If we see the keyword `fn`, then we assume that
1529 // we are parsing an async fn proto, and not a call.
1530 // We therefore put back all tokens consumed by the async
1531 // prefix...
1532 put_back_token(pc);
1533 put_back_token(pc);
1534
1535 return ast_parse_primary_type_expr(pc);
1536 }
1537
1538 AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);1507 AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);
1539 while (true) {1508 while (true) {
1540 AstNode *suffix = ast_parse_suffix_op(pc);1509 AstNode *suffix = ast_parse_suffix_op(pc);
...@@ -2187,23 +2156,6 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {...@@ -2187,23 +2156,6 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {
2187 return res;2156 return res;
2188}2157}
21892158
2190// FnCC
2191// <- KEYWORD_extern
2192// / KEYWORD_async
2193static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) {
2194 AstNodeFnProto res = {};
2195 if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
2196 res.is_async = true;
2197 return Optional<AstNodeFnProto>::some(res);
2198 }
2199 if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) {
2200 res.is_extern = true;
2201 return Optional<AstNodeFnProto>::some(res);
2202 }
2203
2204 return Optional<AstNodeFnProto>::none();
2205}
2206
2207// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType2159// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
2208static AstNode *ast_parse_param_decl(ParseContext *pc) {2160static AstNode *ast_parse_param_decl(ParseContext *pc) {
2209 Buf doc_comments = BUF_INIT;2161 Buf doc_comments = BUF_INIT;