| author | |
| committer | |
| log | a0ca30ce014f4abd9d31ea335e8860fd1b110495 |
| tree | 577b3043e5d720b0916589bf3f9aa07a94b9baa5 |
| parent | fd7c7be33c95fd1bd77010378b407fc9fb4933e2 |
| signature | Commit is signed but in an unrecognized format. |
6 files changed, 79 insertions(+), 114 deletions(-)
lib/std/builtin.zig+16| ... | ... | @@ -348,6 +348,22 @@ pub const Endian = enum { |
| 348 | 348 | Little, |
| 349 | 349 | }; |
| 350 | 350 | |
| 351 | /// This data structure is used by the Zig language code generation and | |
| 352 | /// therefore must be kept in sync with the compiler implementation. | |
| 353 | pub const OutType = enum { | |
| 354 | Unknown, | |
| 355 | Exe, | |
| 356 | Lib, | |
| 357 | Obj, | |
| 358 | }; | |
| 359 | ||
| 360 | /// This data structure is used by the Zig language code generation and | |
| 361 | /// therefore must be kept in sync with the compiler implementation. | |
| 362 | pub const LinkType = enum { | |
| 363 | Static, | |
| 364 | Dynamic, | |
| 365 | }; | |
| 366 | ||
| 351 | 367 | /// This data structure is used by the Zig language code generation and |
| 352 | 368 | /// therefore must be kept in sync with the compiler implementation. |
| 353 | 369 | pub const Version = struct { |
lib/std/special/start.zig+43-12| ... | ... | @@ -19,21 +19,52 @@ const is_mips = switch (builtin.arch) { |
| 19 | 19 | }; |
| 20 | 20 | |
| 21 | 21 | comptime { |
| 22 | if (builtin.link_libc) { | |
| 23 | @export("main", main, .Strong); | |
| 24 | } else if (builtin.os == .windows) { | |
| 25 | @export("WinMainCRTStartup", WinMainCRTStartup, .Strong); | |
| 26 | } else if (is_wasm and builtin.os == .freestanding) { | |
| 27 | @export("_start", wasm_freestanding_start, .Strong); | |
| 28 | } else if (builtin.os == .uefi) { | |
| 29 | @export("EfiMain", EfiMain, .Strong); | |
| 30 | } else if (is_mips) { | |
| 31 | if (!@hasDecl(root, "__start")) @export("__start", _start, .Strong); | |
| 32 | } else { | |
| 33 | if (!@hasDecl(root, "_start")) @export("_start", _start, .Strong); | |
| 22 | switch (builtin.output_type) { | |
| 23 | .Unknown => unreachable, | |
| 24 | .Exe => { | |
| 25 | if (builtin.link_libc) { | |
| 26 | if (!@hasDecl(root, "main") or | |
| 27 | @typeInfo(@typeOf(root.main)).Fn.calling_convention != .C) | |
| 28 | { | |
| 29 | @export("main", main, .Weak); | |
| 30 | } | |
| 31 | } else if (builtin.os == .windows) { | |
| 32 | if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup")) { | |
| 33 | @export("WinMainCRTStartup", WinMainCRTStartup, .Strong); | |
| 34 | } | |
| 35 | } else if (is_wasm and builtin.os == .freestanding) { | |
| 36 | if (!@hasDecl(root, "_start")) @export("_start", wasm_freestanding_start, .Strong); | |
| 37 | } else if (builtin.os == .uefi) { | |
| 38 | if (!@hasDecl(root, "EfiMain")) @export("EfiMain", EfiMain, .Strong); | |
| 39 | } else if (is_mips) { | |
| 40 | if (!@hasDecl(root, "__start")) @export("__start", _start, .Strong); | |
| 41 | } else { | |
| 42 | if (!@hasDecl(root, "_start")) @export("_start", _start, .Strong); | |
| 43 | } | |
| 44 | }, | |
| 45 | .Lib => { | |
| 46 | if (builtin.os == .windows and builtin.link_type == .Dynamic and | |
| 47 | !@hasDecl(root, "_DllMainCRTStartup")) | |
| 48 | { | |
| 49 | @export("_DllMainCRTStartup", _DllMainCRTStartup, .Strong); | |
| 50 | } | |
| 51 | }, | |
| 52 | .Obj => {}, | |
| 34 | 53 | } |
| 35 | 54 | } |
| 36 | 55 | |
| 56 | stdcallcc fn _DllMainCRTStartup( | |
| 57 | hinstDLL: std.os.windows.HINSTANCE, | |
| 58 | fdwReason: std.os.windows.DWORD, | |
| 59 | lpReserved: std.os.windows.LPVOID, | |
| 60 | ) std.os.windows.BOOL { | |
| 61 | if (@hasDecl(root, "DllMain")) { | |
| 62 | return root.DllMain(hinstDLL, fdwReason, lpReserved); | |
| 63 | } | |
| 64 | ||
| 65 | return std.os.windows.TRUE; | |
| 66 | } | |
| 67 | ||
| 37 | 68 | extern fn wasm_freestanding_start() void { |
| 38 | 69 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 39 | 70 | // and we want fewer call frames in stack traces. |
lib/std/special/start_lib.zig deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | // This file is included in the compilation unit when exporting a DLL on windows. | |
| 2 | ||
| 3 | const root = @import("root"); | |
| 4 | const std = @import("std"); | |
| 5 | const builtin = @import("builtin"); | |
| 6 | ||
| 7 | comptime { | |
| 8 | @export("_DllMainCRTStartup", _DllMainCRTStartup, builtin.GlobalLinkage.Strong); | |
| 9 | } | |
| 10 | ||
| 11 | stdcallcc fn _DllMainCRTStartup( | |
| 12 | hinstDLL: std.os.windows.HINSTANCE, | |
| 13 | fdwReason: std.os.windows.DWORD, | |
| 14 | lpReserved: std.os.windows.LPVOID, | |
| 15 | ) std.os.windows.BOOL { | |
| 16 | if (@hasDecl(root, "DllMain")) { | |
| 17 | return root.DllMain(hinstDLL, fdwReason, lpReserved); | |
| 18 | } | |
| 19 | ||
| 20 | return std.os.windows.TRUE; | |
| 21 | } |
src/all_types.hpp-2| ... | ... | @@ -2061,7 +2061,6 @@ struct CodeGen { |
| 2061 | 2061 | ZigList<TldVar *> global_vars; |
| 2062 | 2062 | |
| 2063 | 2063 | ZigFn *cur_fn; |
| 2064 | ZigFn *main_fn; | |
| 2065 | 2064 | ZigFn *panic_fn; |
| 2066 | 2065 | |
| 2067 | 2066 | ZigFn *largest_frame_fn; |
| ... | ... | @@ -2081,7 +2080,6 @@ struct CodeGen { |
| 2081 | 2080 | uint32_t target_abi_index; |
| 2082 | 2081 | uint32_t target_oformat_index; |
| 2083 | 2082 | bool is_big_endian; |
| 2084 | bool have_pub_main; | |
| 2085 | 2083 | bool have_c_main; |
| 2086 | 2084 | bool have_winmain; |
| 2087 | 2085 | bool have_winmain_crt_startup; |
src/analyze.cpp-38| ... | ... | @@ -3304,17 +3304,6 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node) { |
| 3304 | 3304 | return fn_entry; |
| 3305 | 3305 | } |
| 3306 | 3306 | |
| 3307 | static bool scope_is_root_decls(Scope *scope) { | |
| 3308 | while (scope) { | |
| 3309 | if (scope->id == ScopeIdDecls) { | |
| 3310 | ScopeDecls *scope_decls = (ScopeDecls *)scope; | |
| 3311 | return is_top_level_struct(scope_decls->container_type); | |
| 3312 | } | |
| 3313 | scope = scope->parent; | |
| 3314 | } | |
| 3315 | zig_unreachable(); | |
| 3316 | } | |
| 3317 | ||
| 3318 | 3307 | ZigType *get_test_fn_type(CodeGen *g) { |
| 3319 | 3308 | if (g->test_fn_type) |
| 3320 | 3309 | return g->test_fn_type; |
| ... | ... | @@ -3353,7 +3342,6 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, G |
| 3353 | 3342 | } |
| 3354 | 3343 | |
| 3355 | 3344 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 3356 | ZigType *import = tld_fn->base.import; | |
| 3357 | 3345 | AstNode *source_node = tld_fn->base.source_node; |
| 3358 | 3346 | if (source_node->type == NodeTypeFnProto) { |
| 3359 | 3347 | AstNodeFnProto *fn_proto = &source_node->data.fn_proto; |
| ... | ... | @@ -3433,12 +3421,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 3433 | 3421 | if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) { |
| 3434 | 3422 | fn_table_entry->inferred_async_node = fn_table_entry->proto_node; |
| 3435 | 3423 | } |
| 3436 | ||
| 3437 | if (scope_is_root_decls(tld_fn->base.parent_scope) && import == g->root_import) { | |
| 3438 | if (g->have_pub_main && buf_eql_str(tld_fn->base.name, "main")) { | |
| 3439 | g->main_fn = fn_table_entry; | |
| 3440 | } | |
| 3441 | } | |
| 3442 | 3424 | } else if (source_node->type == NodeTypeTestDecl) { |
| 3443 | 3425 | ZigFn *fn_table_entry = create_fn_raw(g, FnInlineAuto); |
| 3444 | 3426 | |
| ... | ... | @@ -4813,26 +4795,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu |
| 4813 | 4795 | ast_print(stderr, root_node, 0); |
| 4814 | 4796 | } |
| 4815 | 4797 | |
| 4816 | if (source_kind == SourceKindRoot) { | |
| 4817 | // Look for main | |
| 4818 | for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) { | |
| 4819 | AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i); | |
| 4820 | ||
| 4821 | if (top_level_decl->type == NodeTypeFnDef) { | |
| 4822 | AstNode *proto_node = top_level_decl->data.fn_def.fn_proto; | |
| 4823 | assert(proto_node->type == NodeTypeFnProto); | |
| 4824 | Buf *proto_name = proto_node->data.fn_proto.name; | |
| 4825 | ||
| 4826 | bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub); | |
| 4827 | if (is_pub) { | |
| 4828 | if (buf_eql_str(proto_name, "main")) { | |
| 4829 | g->have_pub_main = true; | |
| 4830 | } | |
| 4831 | } | |
| 4832 | } | |
| 4833 | } | |
| 4834 | } | |
| 4835 | ||
| 4836 | 4798 | for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) { |
| 4837 | 4799 | AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i); |
| 4838 | 4800 | scan_decls(g, import_entry->data.structure.decls_scope, top_level_decl); |
src/codegen.cpp+20-41| ... | ... | @@ -8229,7 +8229,7 @@ TargetSubsystem detect_subsystem(CodeGen *g) { |
| 8229 | 8229 | if (g->zig_target->os == OsWindows) { |
| 8230 | 8230 | if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic)) |
| 8231 | 8231 | return TargetSubsystemAuto; |
| 8232 | if (g->have_c_main || g->have_pub_main || g->is_test_build) | |
| 8232 | if (g->have_c_main || g->is_test_build) | |
| 8233 | 8233 | return TargetSubsystemConsole; |
| 8234 | 8234 | if (g->have_winmain || g->have_winmain_crt_startup) |
| 8235 | 8235 | return TargetSubsystemWindows; |
| ... | ... | @@ -8375,6 +8375,24 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 8375 | 8375 | const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little"; |
| 8376 | 8376 | buf_appendf(contents, "pub const endian = %s;\n", endian_str); |
| 8377 | 8377 | } |
| 8378 | const char *out_type = nullptr; | |
| 8379 | switch (g->out_type) { | |
| 8380 | case OutTypeUnknown: | |
| 8381 | out_type = "Unknown"; | |
| 8382 | break; | |
| 8383 | case OutTypeExe: | |
| 8384 | out_type = "Exe"; | |
| 8385 | break; | |
| 8386 | case OutTypeLib: | |
| 8387 | out_type = "Lib"; | |
| 8388 | break; | |
| 8389 | case OutTypeObj: | |
| 8390 | out_type = "Obj"; | |
| 8391 | break; | |
| 8392 | } | |
| 8393 | buf_appendf(contents, "pub const output_type = OutType.%s;\n", out_type); | |
| 8394 | const char *link_type = g->is_dynamic ? "Dynamic" : "Static"; | |
| 8395 | buf_appendf(contents, "pub const link_type = LinkType.%s;\n", link_type); | |
| 8378 | 8396 | buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); |
| 8379 | 8397 | buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); |
| 8380 | 8398 | buf_appendf(contents, "pub const os = Os.%s;\n", cur_os); |
| ... | ... | @@ -9148,38 +9166,6 @@ static Buf *get_resolved_root_src_path(CodeGen *g) { |
| 9148 | 9166 | return resolved_path; |
| 9149 | 9167 | } |
| 9150 | 9168 | |
| 9151 | static bool want_startup_code(CodeGen *g) { | |
| 9152 | // Test builds get handled separately. | |
| 9153 | if (g->is_test_build) | |
| 9154 | return false; | |
| 9155 | ||
| 9156 | // WASM freestanding can still have an entry point but other freestanding targets do not. | |
| 9157 | if (g->zig_target->os == OsFreestanding && !target_is_wasm(g->zig_target)) | |
| 9158 | return false; | |
| 9159 | ||
| 9160 | // Declaring certain export functions means skipping the start code | |
| 9161 | if (g->have_c_main || g->have_winmain || g->have_winmain_crt_startup) | |
| 9162 | return false; | |
| 9163 | ||
| 9164 | // If there is a pub main in the root source file, that means we need start code. | |
| 9165 | if (g->have_pub_main) { | |
| 9166 | return true; | |
| 9167 | } else { | |
| 9168 | if (g->zig_target->os == OsUefi) | |
| 9169 | return false; | |
| 9170 | } | |
| 9171 | ||
| 9172 | if (g->out_type == OutTypeExe) { | |
| 9173 | // For build-exe, we might add start code even though there is no pub main, so that the | |
| 9174 | // programmer gets the "no pub main" compile error. However if linking libc and there is | |
| 9175 | // a C source file, that might have main(). | |
| 9176 | return g->c_source_files.length == 0 || g->libc_link_lib == nullptr; | |
| 9177 | } | |
| 9178 | ||
| 9179 | // For objects and libraries, and we don't have pub main, no start code. | |
| 9180 | return false; | |
| 9181 | } | |
| 9182 | ||
| 9183 | 9169 | static void gen_root_source(CodeGen *g) { |
| 9184 | 9170 | Buf *resolved_path = get_resolved_root_src_path(g); |
| 9185 | 9171 | if (resolved_path == nullptr) |
| ... | ... | @@ -9241,21 +9227,14 @@ static void gen_root_source(CodeGen *g) { |
| 9241 | 9227 | assert(g->panic_fn != nullptr); |
| 9242 | 9228 | } |
| 9243 | 9229 | |
| 9244 | ||
| 9245 | 9230 | if (!g->error_during_imports) { |
| 9246 | 9231 | semantic_analyze(g); |
| 9247 | 9232 | } |
| 9248 | 9233 | report_errors_and_maybe_exit(g); |
| 9249 | 9234 | |
| 9250 | if (want_startup_code(g)) { | |
| 9235 | if (!g->is_test_build) { | |
| 9251 | 9236 | g->start_import = add_special_code(g, create_start_pkg(g, g->root_package), "start.zig"); |
| 9252 | 9237 | } |
| 9253 | if (g->zig_target->os == OsWindows && !g->have_dllmain_crt_startup && | |
| 9254 | g->out_type == OutTypeLib && g->is_dynamic) | |
| 9255 | { | |
| 9256 | g->start_import = add_special_code(g, create_start_pkg(g, g->root_package), "start_lib.zig"); | |
| 9257 | } | |
| 9258 | ||
| 9259 | 9238 | if (!g->error_during_imports) { |
| 9260 | 9239 | semantic_analyze(g); |
| 9261 | 9240 | } |