| author | |
| committer | |
| log | cbc4e59e6805d27f0e889c0a9ff8488376cea5c0 |
| tree | 0f5ca27a04c354639a61c65c6acb7e867fb0c5bf |
| parent | ccca4b5a5e98dd96aaeb365af6c1cfbe87dca181 |
| parent | 30194f27fb5521b11442f1d13474eac3915051d7 |
| signature |
closes #45025 files changed, 17 insertions(+), 3 deletions(-)
doc/langref.html.in+1-1| ... | ... | @@ -7399,7 +7399,7 @@ comptime { |
| 7399 | 7399 | @export(internalName, .{ .name = "foo", .linkage = .Strong }); |
| 7400 | 7400 | } |
| 7401 | 7401 | |
| 7402 | extern fn internalName() void {} | |
| 7402 | fn internalName() callconv(.C) void {} | |
| 7403 | 7403 | {#code_end#} |
| 7404 | 7404 | <p>This is equivalent to:</p> |
| 7405 | 7405 | {#code_begin|obj#} |
lib/std/zig/parser_test.zig+2| ... | ... | @@ -92,10 +92,12 @@ test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" { |
| 92 | 92 | \\nakedcc fn foo1() void {} |
| 93 | 93 | \\stdcallcc fn foo2() void {} |
| 94 | 94 | \\extern fn foo3() void {} |
| 95 | \\extern "mylib" fn foo4() void {} | |
| 95 | 96 | , |
| 96 | 97 | \\fn foo1() callconv(.Naked) void {} |
| 97 | 98 | \\fn foo2() callconv(.Stdcall) void {} |
| 98 | 99 | \\fn foo3() callconv(.C) void {} |
| 100 | \\fn foo4() callconv(.C) void {} | |
| 99 | 101 | \\ |
| 100 | 102 | ); |
| 101 | 103 | } |
lib/std/zig/render.zig+1| ... | ... | @@ -1396,6 +1396,7 @@ fn renderExpression( |
| 1396 | 1396 | try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export |
| 1397 | 1397 | } else { |
| 1398 | 1398 | cc_rewrite_str = ".C"; |
| 1399 | fn_proto.lib_name = null; | |
| 1399 | 1400 | } |
| 1400 | 1401 | } |
| 1401 | 1402 |
src/parser.cpp+3| ... | ... | @@ -689,6 +689,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B |
| 689 | 689 | |
| 690 | 690 | AstNode *res = fn_proto; |
| 691 | 691 | if (body != nullptr) { |
| 692 | if (fn_proto->data.fn_proto.is_extern) { | |
| 693 | ast_error(pc, first, "Extern functions have no body"); | |
| 694 | } | |
| 692 | 695 | res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto); |
| 693 | 696 | res->data.fn_def.fn_proto = fn_proto; |
| 694 | 697 | res->data.fn_def.body = body; |
test/compile_errors.zig+10-2| ... | ... | @@ -3,15 +3,23 @@ const builtin = @import("builtin"); |
| 3 | 3 | const Target = @import("std").Target; |
| 4 | 4 | |
| 5 | 5 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6 | cases.addTest("", | |
| 6 | cases.addTest("access invalid @typeInfo decl", | |
| 7 | 7 | \\const A = B; |
| 8 | 8 | \\test "Crash" { |
| 9 | \\ _ = @typeInfo(@This()).Struct.decls; | |
| 9 | \\ _ = @typeInfo(@This()).Struct.decls[0]; | |
| 10 | 10 | \\} |
| 11 | 11 | , &[_][]const u8{ |
| 12 | 12 | "tmp.zig:1:11: error: use of undeclared identifier 'B'", |
| 13 | 13 | }); |
| 14 | 14 | |
| 15 | cases.addTest("reject extern function definitions with body", | |
| 16 | \\extern "c" fn definitelyNotInLibC(a: i32, b: i32) i32 { | |
| 17 | \\ return a + b; | |
| 18 | \\} | |
| 19 | , &[_][]const u8{ | |
| 20 | "tmp.zig:1:1: error: Extern functions have no body", | |
| 21 | }); | |
| 22 | ||
| 15 | 23 | cases.addTest("duplicate field in anonymous struct literal", |
| 16 | 24 | \\export fn entry() void { |
| 17 | 25 | \\ const anon = .{ |