From 42b79d19c176be4733b5150e19230aa02f882e7b Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 6 Feb 2026 00:55:57 +0100 Subject: [PATCH] Update all stub methods. --- lib/std/core/private/main_stub.c3 | 152 ++++++------------ src/compiler/sema_decls.c | 66 ++------ .../concurrency/atomic_load_store_debug.c3t | 6 +- test/test_suite/debug_symbols/defer_macro.c3t | 2 +- 4 files changed, 63 insertions(+), 163 deletions(-) diff --git a/lib/std/core/private/main_stub.c3 b/lib/std/core/private/main_stub.c3 index 00a32fbe3..78986da65 100644 --- a/lib/std/core/private/main_stub.c3 +++ b/lib/std/core/private/main_stub.c3 @@ -7,19 +7,26 @@ macro usz _strlen(ptr) @private return len; } -macro int @main_to_err_main(#m, int, char**) +macro int @main_no_args(#m, int, char**) { - if (catch #m()) return 1; - return 0; + $if $typeof(#m()) == void: + #m(); + return 0; + $else + return #m(); + $endif } -macro int @main_to_int_main(#m, int, char**) + +macro int @main_args(#m, int argc, char** argv) { - return #m(); -} -macro int @main_to_void_main(#m, int, char**) -{ - #m(); - return 0; + String[] list = args_to_strings(argc, argv); + defer free(list.ptr); + $if $typeof(#m(list)) == void: + #m(list); + return 0; + $else + return #m(list); + $endif } macro String[] args_to_strings(int argc, char** argv) @private @@ -35,21 +42,6 @@ macro String[] args_to_strings(int argc, char** argv) @private } -macro int @main_to_err_main_args(#m, int argc, char** argv) -{ - String[] list = args_to_strings(argc, argv); - defer free(list.ptr); - if (catch #m(list)) return 1; - return 0; -} - -macro int @main_to_int_main_args(#m, int argc, char** argv) -{ - String[] list = args_to_strings(argc, argv); - defer free(list.ptr); - return #m(list); -} - macro int @_main_runner(#m, int argc, char** argv) { String[] list = args_to_strings(argc, argv); @@ -57,14 +49,6 @@ macro int @_main_runner(#m, int argc, char** argv) return #m(list) ? 0 : 1; } -macro int @main_to_void_main_args(#m, int argc, char** argv) -{ - String[] list = args_to_strings(argc, argv); - defer free(list.ptr); - #m(list); - return 0; -} - module std::core::main_stub @if(env::WIN32); import std::os::win32; @@ -105,92 +89,55 @@ macro void release_wargs(String[] list) @private free(list.ptr); } -macro int @win_to_err_main_noargs(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) +macro int @win_main_no_args(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) { win32_set_utf8_codepage(); - if (catch #m()) return 1; - return 0; -} -macro int @win_to_int_main_noargs(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) -{ - win32_set_utf8_codepage(); - return #m(); + $if $typeof(#m()) == void: + #m(); + return 0; + $else + return #m(); + $endif } -macro int @win_to_void_main_noargs(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) -{ - win32_set_utf8_codepage(); - #m(); - return 0; -} - -macro int @win_to_err_main_args(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) +macro int @win_main_args(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) { win32_set_utf8_codepage(); String[] args = win_command_line_to_strings(cmd_line); defer release_wargs(args); - if (catch #m(args)) return 1; - return 0; + $if $typeof(#m(args)) == void: + #m(args); + return 0; + $else + return #m(args); + $endif } -macro int @win_to_int_main_args(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) +macro int @win_main(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) { win32_set_utf8_codepage(); String[] args = win_command_line_to_strings(cmd_line); defer release_wargs(args); - return #m(args); + $if $typeof(#m(handle, prev_handle, args, show_cmd)) == void: + #m(handle, prev_handle, args, show_cmd); + return 0; + $else + return #m(handle, prev_handle, args, show_cmd); + $endif } -macro int @win_to_void_main_args(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) -{ - win32_set_utf8_codepage(); - String[] args = win_command_line_to_strings(cmd_line); - defer release_wargs(args); - #m(args); - return 0; -} -macro int @win_to_err_main(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) -{ - win32_set_utf8_codepage(); - String[] args = win_command_line_to_strings(cmd_line); - defer release_wargs(args); - if (catch #m(handle, prev_handle, args, show_cmd)) return 1; - return 0; -} - -macro int @win_to_int_main(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) -{ - win32_set_utf8_codepage(); - String[] args = win_command_line_to_strings(cmd_line); - defer release_wargs(args); - return #m(handle, prev_handle, args, show_cmd); -} - -macro int @win_to_void_main(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) -{ - win32_set_utf8_codepage(); - String[] args = win_command_line_to_strings(cmd_line); - defer release_wargs(args); - #m(handle, prev_handle, args, show_cmd); - return 0; -} - -macro int @wmain_to_err_main_args(#m, int argc, Char16** argv) +macro int @wmain_main(#m, int argc, Char16** argv) { win32_set_utf8_codepage(); String[] args = wargs_strings(argc, argv); defer release_wargs(args); - if (catch #m(args)) return 1; - return 1; -} - -macro int @wmain_to_int_main_args(#m, int argc, Char16** argv) -{ - win32_set_utf8_codepage(); - String[] args = wargs_strings(argc, argv); - defer release_wargs(args); - return #m(args); + $if $typeof(#m(args)) == void: + #m(args); + return 0; + $else + return #m(args); + $endif } macro int @_wmain_runner(#m, int argc, Char16** argv) @@ -200,12 +147,3 @@ macro int @_wmain_runner(#m, int argc, Char16** argv) defer release_wargs(args); return #m(args) ? 0 : 1; } - -macro int @wmain_to_void_main_args(#m, int argc, Char16** argv) -{ - win32_set_utf8_codepage(); - String[] args = wargs_strings(argc, argv); - defer release_wargs(args); - #m(args); - return 0; -} diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 543c2ce37..01c11d04c 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -4080,7 +4080,7 @@ Decl *sema_create_runner_main(SemaContext *context, Decl *decl) return function; } -static inline Decl *sema_create_synthetic_main(SemaContext *context, Decl *decl, MainType main, bool int_return, bool err_return, bool is_winmain, bool is_wmain) +static inline Decl *sema_create_synthetic_main(SemaContext *context, Decl *decl, MainType main, bool int_return, bool is_winmain, bool is_wmain) { Decl *function = decl_new(DECL_FUNC, NULL, decl->span); function->is_export = true; @@ -4125,70 +4125,34 @@ static inline Decl *sema_create_synthetic_main(SemaContext *context, Decl *decl, Ast *body = new_ast(AST_COMPOUND_STMT, decl->span); AstId *next = &body->compound_stmt.first_stmt; Ast *ret_stmt = new_ast(AST_RETURN_STMT, decl->span); - int type = int_return ? 1 : (err_return ? 2 : 0); const char *main_invoker; switch (main) { case MAIN_TYPE_ARGS: if (is_winmain) { - switch (type) - { - case 0 : main_invoker = "@win_to_void_main_args"; goto NEXT; - case 1 : main_invoker = "@win_to_int_main_args"; goto NEXT; - case 2 : main_invoker = "@win_to_err_main_args"; goto NEXT; - default: UNREACHABLE - } + main_invoker = "@win_main_args"; } - if (is_wmain) + else if (is_wmain) { - switch (type) - { - case 0 : main_invoker = "@wmain_to_void_main_args"; goto NEXT; - case 1 : main_invoker = "@wmain_to_int_main_args"; goto NEXT; - case 2 : main_invoker = "@wmain_to_err_main_args"; goto NEXT; - default: UNREACHABLE - } + main_invoker = "@wmain_main"; } - switch (type) + else { - case 0: main_invoker = "@main_to_void_main_args"; goto NEXT; - case 1: main_invoker = "@main_to_int_main_args"; goto NEXT; - case 2: main_invoker = "@main_to_err_main_args"; goto NEXT; - default: UNREACHABLE + main_invoker = "@main_args"; } + break; case MAIN_TYPE_NO_ARGS: ASSERT(!is_wmain); - if (is_winmain) - { - switch (type) - { - case 0 : main_invoker = "@win_to_void_main_noargs"; goto NEXT; - case 1 : main_invoker = "@win_to_int_main_noargs"; goto NEXT; - case 2 : main_invoker = "@win_to_err_main_noargs"; goto NEXT; - default: UNREACHABLE - } - } - switch (type) - { - case 0 : main_invoker = "@main_to_void_main"; goto NEXT; - case 1 : main_invoker = "@main_to_int_main"; goto NEXT; - case 2 : main_invoker = "@main_to_err_main"; goto NEXT; - default: UNREACHABLE - } + main_invoker = is_winmain ? "@win_main_no_args" : "@main_no_args"; + break; case MAIN_TYPE_WIN: ASSERT(is_winmain); - switch (type) - { - case 0 : main_invoker = "@win_to_void_main"; goto NEXT; - case 1 : main_invoker = "@win_to_int_main"; goto NEXT; - case 2 : main_invoker = "@win_to_err_main"; goto NEXT; - default: UNREACHABLE - } + main_invoker = "@win_main"; + break; default: UNREACHABLE } - NEXT:; const char *kw_main_invoker = symtab_preset(main_invoker, TOKEN_AT_IDENT); Decl *d = sema_find_symbol(context, kw_main_invoker); if (!d) @@ -4222,15 +4186,13 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) bool is_win32 = compiler.platform.os == OS_TYPE_WIN32; if (decl->visibility != VISIBLE_PUBLIC) { - SEMA_ERROR(decl, "A main function must be public."); - return false; + RETURN_SEMA_ERROR(decl, "A main function must be public."); } Signature *signature = &decl->func_decl.signature; TypeInfo *rtype_info = type_infoptr(signature->rtype); Type *rtype = rtype_info->type; bool is_int_return = true; - bool is_err_return = false; - if (!is_err_return && type_is_optional(rtype)) + if (type_is_optional(rtype)) { RETURN_SEMA_ERROR(rtype_info, "The return type of 'main' cannot be an optional."); } @@ -4269,7 +4231,7 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) } bool is_wmain = is_win32 && !is_winmain && type != MAIN_TYPE_NO_ARGS; compiler.build.win.use_win_subsystem = is_winmain && is_win32; - function = sema_create_synthetic_main(context, decl, type, is_int_return, is_err_return, is_winmain, is_wmain); + function = sema_create_synthetic_main(context, decl, type, is_int_return, is_winmain, is_wmain); if (!decl_ok(function)) return false; REGISTER_MAIN: context->unit->main_function = function; diff --git a/test/test_suite/concurrency/atomic_load_store_debug.c3t b/test/test_suite/concurrency/atomic_load_store_debug.c3t index c4ddf4cf1..2eb0af98f 100644 --- a/test/test_suite/concurrency/atomic_load_store_debug.c3t +++ b/test/test_suite/concurrency/atomic_load_store_debug.c3t @@ -130,6 +130,6 @@ declare i1 @llvm.expect.i1(i1, i1) !46 = !DILocation(line: 10, column: 9, scope: !39) !47 = !DILocalVariable(name: ".anon", arg: 2, scope: !39, file: !7, line: 10, type: !42) !48 = !DILocation( -!49 = distinct !DISubprogram(name: "@main_to_void_main", linkageName: "@main_to_void_main", scope: !50, file: !50 -!50 = !DIFile(filename: "main_stub.c3", directory: -!51 = !DILocation( +!49 = distinct !DISubprogram(name: "@main_no_args", linkageName: "@main_no_args" +!50 = !DIFile(filename: "main_stub.c3" +!51 = !DILocation( \ No newline at end of file diff --git a/test/test_suite/debug_symbols/defer_macro.c3t b/test/test_suite/debug_symbols/defer_macro.c3t index 538d469d4..7dee1d888 100644 --- a/test/test_suite/debug_symbols/defer_macro.c3t +++ b/test/test_suite/debug_symbols/defer_macro.c3t @@ -755,7 +755,7 @@ no_match: ; preds = %compare !140 = !DILocation(line: 15, column: 8, scope: !135) !141 = !DILocalVariable(name: ".anon", arg: 2, scope: !135, file: !7 !142 = !DILocalVariable(name: "list", scope: !143, file: !7 -!143 = distinct !DISubprogram(name: "@main_to_int_main_args", linkageName: "@main_to_int_main_args", scope: !144, file: !144 +!143 = distinct !DISubprogram(name: "@main_args", linkageName: "@main_args", scope: !144, file: !144 !144 = !DIFile(filename: "main_stub.c3" !145 = !DILocation !146 = !DILocalVariable(name: "list", scope: !147, file: !7