remove nakedcc/stdcallcc/async fn/extern fn fnproto
This commit is contained in:
@@ -800,7 +800,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
||||
.Keyword_for,
|
||||
.Keyword_if,
|
||||
.Keyword_inline,
|
||||
.Keyword_nakedcc,
|
||||
.Keyword_noalias,
|
||||
.Keyword_noinline,
|
||||
.Keyword_nosuspend,
|
||||
@@ -813,7 +812,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
||||
.Keyword_return,
|
||||
.Keyword_linksection,
|
||||
.Keyword_callconv,
|
||||
.Keyword_stdcallcc,
|
||||
.Keyword_struct,
|
||||
.Keyword_suspend,
|
||||
.Keyword_switch,
|
||||
|
||||
@@ -10088,7 +10088,7 @@ TopLevelDecl
|
||||
/ (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
|
||||
/ KEYWORD_usingnamespace Expr SEMICOLON
|
||||
|
||||
FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
|
||||
FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
|
||||
|
||||
VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
|
||||
|
||||
@@ -10255,11 +10255,6 @@ WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
|
||||
|
||||
LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
|
||||
|
||||
# Fn specific
|
||||
FnCC
|
||||
<- KEYWORD_extern
|
||||
/ KEYWORD_async
|
||||
|
||||
ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
|
||||
|
||||
ParamType
|
||||
|
||||
@@ -875,7 +875,6 @@ pub const Node = struct {
|
||||
return_type: ReturnType,
|
||||
var_args_token: ?TokenIndex,
|
||||
extern_export_inline_token: ?TokenIndex,
|
||||
cc_token: ?TokenIndex,
|
||||
body_node: ?*Node,
|
||||
lib_name: ?*Node, // populated if this is an extern declaration
|
||||
align_expr: ?*Node, // populated if align(A) is present
|
||||
@@ -929,7 +928,6 @@ pub const Node = struct {
|
||||
if (self.visib_token) |visib_token| return visib_token;
|
||||
if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
|
||||
assert(self.lib_name == null);
|
||||
if (self.cc_token) |cc_token| return cc_token;
|
||||
return self.fn_token;
|
||||
}
|
||||
|
||||
|
||||
@@ -335,22 +335,9 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
|
||||
return use_node;
|
||||
}
|
||||
|
||||
/// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
|
||||
/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
|
||||
fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
const cc = parseFnCC(arena, it, tree);
|
||||
const fn_token = eatToken(it, .Keyword_fn) orelse {
|
||||
if (cc) |fnCC| {
|
||||
if (fnCC == .Extern) {
|
||||
putBackToken(it, fnCC.Extern); // 'extern' is also used in ContainerDecl
|
||||
} else {
|
||||
try tree.errors.push(.{
|
||||
.ExpectedToken = .{ .token = it.index, .expected_id = .Keyword_fn },
|
||||
});
|
||||
return error.ParseError;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const fn_token = eatToken(it, .Keyword_fn) orelse return null;
|
||||
const name_token = eatToken(it, .Identifier);
|
||||
const lparen = try expectToken(it, tree, .LParen);
|
||||
const params = try parseParamDeclList(arena, it, tree);
|
||||
@@ -389,7 +376,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
.return_type = return_type,
|
||||
.var_args_token = var_args_token,
|
||||
.extern_export_inline_token = null,
|
||||
.cc_token = null,
|
||||
.body_node = null,
|
||||
.lib_name = null,
|
||||
.align_expr = align_expr,
|
||||
@@ -397,13 +383,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
.callconv_expr = callconv_expr,
|
||||
};
|
||||
|
||||
if (cc) |kind| {
|
||||
switch (kind) {
|
||||
.CC => |token| fn_proto_node.cc_token = token,
|
||||
.Extern => |token| fn_proto_node.extern_export_inline_token = token,
|
||||
}
|
||||
}
|
||||
|
||||
return &fn_proto_node.base;
|
||||
}
|
||||
|
||||
@@ -1196,16 +1175,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
const maybe_async = eatToken(it, .Keyword_async);
|
||||
if (maybe_async) |async_token| {
|
||||
const token_fn = eatToken(it, .Keyword_fn);
|
||||
if (token_fn != null) {
|
||||
// HACK: If we see the keyword `fn`, then we assume that
|
||||
// we are parsing an async fn proto, and not a call.
|
||||
// We therefore put back all tokens consumed by the async
|
||||
// prefix...
|
||||
putBackToken(it, token_fn.?);
|
||||
putBackToken(it, async_token);
|
||||
return parsePrimaryTypeExpr(arena, it, tree);
|
||||
}
|
||||
// TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr
|
||||
var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, .{
|
||||
.ExpectedPrimaryTypeExpr = .{ .token = it.index },
|
||||
});
|
||||
@@ -1778,24 +1747,6 @@ fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
return expr_node;
|
||||
}
|
||||
|
||||
/// FnCC
|
||||
/// <- KEYWORD_nakedcc
|
||||
/// / KEYWORD_stdcallcc
|
||||
/// / KEYWORD_extern
|
||||
/// / KEYWORD_async
|
||||
fn parseFnCC(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?FnCC {
|
||||
if (eatToken(it, .Keyword_nakedcc)) |token| return FnCC{ .CC = token };
|
||||
if (eatToken(it, .Keyword_stdcallcc)) |token| return FnCC{ .CC = token };
|
||||
if (eatToken(it, .Keyword_extern)) |token| return FnCC{ .Extern = token };
|
||||
if (eatToken(it, .Keyword_async)) |token| return FnCC{ .CC = token };
|
||||
return null;
|
||||
}
|
||||
|
||||
const FnCC = union(enum) {
|
||||
CC: TokenIndex,
|
||||
Extern: TokenIndex,
|
||||
};
|
||||
|
||||
/// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
|
||||
fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
|
||||
const doc_comments = try parseDocComment(arena, it, tree);
|
||||
|
||||
@@ -123,22 +123,6 @@ test "zig fmt: trailing comma in fn parameter list" {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Remove nakedcc/stdcallcc once zig 0.6.0 is released. See https://github.com/ziglang/zig/pull/3977
|
||||
test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {
|
||||
try testTransform(
|
||||
\\nakedcc fn foo1() void {}
|
||||
\\stdcallcc fn foo2() void {}
|
||||
\\extern fn foo3() void {}
|
||||
\\extern "mylib" fn foo4() void {}
|
||||
,
|
||||
\\fn foo1() callconv(.Naked) void {}
|
||||
\\fn foo2() callconv(.Stdcall) void {}
|
||||
\\fn foo3() callconv(.C) void {}
|
||||
\\fn foo4() callconv(.C) void {}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: comptime struct field" {
|
||||
try testCanonical(
|
||||
\\const Foo = struct {
|
||||
|
||||
@@ -1413,32 +1413,14 @@ fn renderExpression(
|
||||
try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub
|
||||
}
|
||||
|
||||
// Some extra machinery is needed to rewrite the old-style cc
|
||||
// notation to the new callconv one
|
||||
var cc_rewrite_str: ?[*:0]const u8 = null;
|
||||
if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
|
||||
const tok = tree.tokens.at(extern_export_inline_token);
|
||||
if (tok.id != .Keyword_extern or fn_proto.body_node == null) {
|
||||
try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
|
||||
} else {
|
||||
cc_rewrite_str = ".C";
|
||||
fn_proto.lib_name = null;
|
||||
}
|
||||
try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
|
||||
}
|
||||
|
||||
if (fn_proto.lib_name) |lib_name| {
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
|
||||
}
|
||||
|
||||
if (fn_proto.cc_token) |cc_token| {
|
||||
var str = tree.tokenSlicePtr(tree.tokens.at(cc_token));
|
||||
if (mem.eql(u8, str, "stdcallcc")) {
|
||||
cc_rewrite_str = ".Stdcall";
|
||||
} else if (mem.eql(u8, str, "nakedcc")) {
|
||||
cc_rewrite_str = ".Naked";
|
||||
} else try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
|
||||
}
|
||||
|
||||
const lparen = if (fn_proto.name_token) |name_token| blk: {
|
||||
try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
|
||||
try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name
|
||||
@@ -1528,10 +1510,6 @@ fn renderExpression(
|
||||
try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);
|
||||
try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )
|
||||
} else if (cc_rewrite_str) |str| {
|
||||
try stream.writeAll("callconv(");
|
||||
try stream.writeAll(mem.spanZ(str));
|
||||
try stream.writeAll(") ");
|
||||
}
|
||||
|
||||
switch (fn_proto.return_type) {
|
||||
|
||||
@@ -47,7 +47,6 @@ pub const Token = struct {
|
||||
Keyword.init("for", .Keyword_for),
|
||||
Keyword.init("if", .Keyword_if),
|
||||
Keyword.init("inline", .Keyword_inline),
|
||||
Keyword.init("nakedcc", .Keyword_nakedcc),
|
||||
Keyword.init("noalias", .Keyword_noalias),
|
||||
Keyword.init("noasync", .Keyword_nosuspend), // TODO: remove this
|
||||
Keyword.init("noinline", .Keyword_noinline),
|
||||
@@ -60,7 +59,6 @@ pub const Token = struct {
|
||||
Keyword.init("resume", .Keyword_resume),
|
||||
Keyword.init("return", .Keyword_return),
|
||||
Keyword.init("linksection", .Keyword_linksection),
|
||||
Keyword.init("stdcallcc", .Keyword_stdcallcc),
|
||||
Keyword.init("struct", .Keyword_struct),
|
||||
Keyword.init("suspend", .Keyword_suspend),
|
||||
Keyword.init("switch", .Keyword_switch),
|
||||
@@ -181,7 +179,6 @@ pub const Token = struct {
|
||||
Keyword_for,
|
||||
Keyword_if,
|
||||
Keyword_inline,
|
||||
Keyword_nakedcc,
|
||||
Keyword_noalias,
|
||||
Keyword_noinline,
|
||||
Keyword_nosuspend,
|
||||
@@ -194,7 +191,6 @@ pub const Token = struct {
|
||||
Keyword_resume,
|
||||
Keyword_return,
|
||||
Keyword_linksection,
|
||||
Keyword_stdcallcc,
|
||||
Keyword_struct,
|
||||
Keyword_suspend,
|
||||
Keyword_switch,
|
||||
@@ -306,7 +302,6 @@ pub const Token = struct {
|
||||
.Keyword_for => "for",
|
||||
.Keyword_if => "if",
|
||||
.Keyword_inline => "inline",
|
||||
.Keyword_nakedcc => "nakedcc",
|
||||
.Keyword_noalias => "noalias",
|
||||
.Keyword_noinline => "noinline",
|
||||
.Keyword_nosuspend => "nosuspend",
|
||||
@@ -318,7 +313,6 @@ pub const Token = struct {
|
||||
.Keyword_resume => "resume",
|
||||
.Keyword_return => "return",
|
||||
.Keyword_linksection => "linksection",
|
||||
.Keyword_stdcallcc => "stdcallcc",
|
||||
.Keyword_struct => "struct",
|
||||
.Keyword_suspend => "suspend",
|
||||
.Keyword_switch => "switch",
|
||||
|
||||
@@ -4094,7 +4094,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
|
||||
.return_type = proto_alias.return_type,
|
||||
.var_args_token = null,
|
||||
.extern_export_inline_token = inline_tok,
|
||||
.cc_token = null,
|
||||
.body_node = null,
|
||||
.lib_name = null,
|
||||
.align_expr = null,
|
||||
@@ -4753,7 +4752,6 @@ fn finishTransFnProto(
|
||||
.return_type = .{ .Explicit = return_type_node },
|
||||
.var_args_token = null, // TODO this field is broken in the AST data model
|
||||
.extern_export_inline_token = extern_export_inline_tok,
|
||||
.cc_token = null,
|
||||
.body_node = null,
|
||||
.lib_name = null,
|
||||
.align_expr = align_expr,
|
||||
@@ -5119,7 +5117,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
|
||||
.return_type = .{ .Explicit = &type_of.base },
|
||||
.doc_comments = null,
|
||||
.var_args_token = null,
|
||||
.cc_token = null,
|
||||
.body_node = null,
|
||||
.lib_name = null,
|
||||
.align_expr = null,
|
||||
|
||||
@@ -718,7 +718,6 @@ struct AstNodeFnProto {
|
||||
Buf doc_comments;
|
||||
|
||||
FnInline fn_inline;
|
||||
bool is_async;
|
||||
|
||||
VisibMod visib_mod;
|
||||
bool auto_err_set;
|
||||
|
||||
@@ -1528,8 +1528,6 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
|
||||
}
|
||||
|
||||
CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {
|
||||
if (fn_proto->is_async)
|
||||
return CallingConventionAsync;
|
||||
// Compatible with the C ABI
|
||||
if (fn_proto->is_extern || fn_proto->is_export)
|
||||
return CallingConventionC;
|
||||
|
||||
@@ -93,7 +93,6 @@ static AstNode *ast_parse_field_init(ParseContext *pc);
|
||||
static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
|
||||
static AstNode *ast_parse_link_section(ParseContext *pc);
|
||||
static AstNode *ast_parse_callconv(ParseContext *pc);
|
||||
static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc);
|
||||
static AstNode *ast_parse_param_decl(ParseContext *pc);
|
||||
static AstNode *ast_parse_param_type(ParseContext *pc);
|
||||
static AstNode *ast_parse_if_prefix(ParseContext *pc);
|
||||
@@ -707,7 +706,6 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
|
||||
fn_proto->column = first->start_column;
|
||||
fn_proto->data.fn_proto.visib_mod = visib_mod;
|
||||
fn_proto->data.fn_proto.doc_comments = *doc_comments;
|
||||
// ast_parse_fn_cc may set it
|
||||
if (!fn_proto->data.fn_proto.is_extern)
|
||||
fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;
|
||||
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
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
|
||||
// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
|
||||
static AstNode *ast_parse_fn_proto(ParseContext *pc) {
|
||||
Token *first = peek_token(pc);
|
||||
AstNodeFnProto fn_cc;
|
||||
Token *fn;
|
||||
if (ast_parse_fn_cc(pc).unwrap(&fn_cc)) {
|
||||
// The extern keyword for fn CC is also used for container decls.
|
||||
// We therefore put it back, as allow container decl to consume it
|
||||
// later.
|
||||
if (fn_cc.is_extern) {
|
||||
fn = eat_token_if(pc, TokenIdKeywordFn);
|
||||
if (fn == nullptr) {
|
||||
put_back_token(pc);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
fn = expect_token(pc, TokenIdKeywordFn);
|
||||
}
|
||||
} else {
|
||||
fn_cc = {};
|
||||
fn = eat_token_if(pc, TokenIdKeywordFn);
|
||||
if (fn == nullptr)
|
||||
return nullptr;
|
||||
Token *first = eat_token_if(pc, TokenIdKeywordFn);
|
||||
if (first == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Token *identifier = eat_token_if(pc, TokenIdSymbol);
|
||||
@@ -830,7 +810,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
|
||||
}
|
||||
|
||||
AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);
|
||||
res->data.fn_proto = fn_cc;
|
||||
res->data.fn_proto = {};
|
||||
res->data.fn_proto.name = token_buf(identifier);
|
||||
res->data.fn_proto.params = params;
|
||||
res->data.fn_proto.align_expr = align_expr;
|
||||
@@ -1524,17 +1504,6 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
|
||||
static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
|
||||
Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
|
||||
if (async_token) {
|
||||
if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
|
||||
// HACK: If we see the keyword `fn`, then we assume that
|
||||
// we are parsing an async fn proto, and not a call.
|
||||
// We therefore put back all tokens consumed by the async
|
||||
// prefix...
|
||||
put_back_token(pc);
|
||||
put_back_token(pc);
|
||||
|
||||
return ast_parse_primary_type_expr(pc);
|
||||
}
|
||||
|
||||
AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);
|
||||
while (true) {
|
||||
AstNode *suffix = ast_parse_suffix_op(pc);
|
||||
@@ -2187,23 +2156,6 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// FnCC
|
||||
// <- KEYWORD_extern
|
||||
// / KEYWORD_async
|
||||
static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) {
|
||||
AstNodeFnProto res = {};
|
||||
if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
|
||||
res.is_async = true;
|
||||
return Optional<AstNodeFnProto>::some(res);
|
||||
}
|
||||
if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) {
|
||||
res.is_extern = true;
|
||||
return Optional<AstNodeFnProto>::some(res);
|
||||
}
|
||||
|
||||
return Optional<AstNodeFnProto>::none();
|
||||
}
|
||||
|
||||
// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
|
||||
static AstNode *ast_parse_param_decl(ParseContext *pc) {
|
||||
Buf doc_comments = BUF_INIT;
|
||||
|
||||
Reference in New Issue
Block a user