diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 599 |
1 files changed, 139 insertions, 460 deletions
diff --git a/src/main.cpp b/src/main.cpp index db2702b19..2a7c90744 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,4 @@ // #define NO_ARRAY_BOUNDS_CHECK - #include "common.cpp" #include "timings.cpp" #include "tokenizer.cpp" @@ -71,6 +70,18 @@ gb_global Timings global_timings = {0}; #include "checker.cpp" #include "docs.cpp" +#include "linker.cpp" + +#if defined(GB_SYSTEM_WINDOWS) && defined(ODIN_TILDE_BACKEND) +#define ALLOW_TILDE 1 +#else +#define ALLOW_TILDE 0 +#endif + +#if ALLOW_TILDE +#include "tilde.cpp" +#endif + #include "llvm_backend.cpp" #if defined(GB_SYSTEM_OSX) @@ -147,422 +158,6 @@ gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt, return exit_code; } - -gb_internal i32 linker_stage(lbGenerator *gen) { - i32 result = 0; - Timings *timings = &global_timings; - - String output_filename = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); - debugf("Linking %.*s\n", LIT(output_filename)); - - // TOOD(Jeroen): Make a `build_paths[BuildPath_Object] to avoid `%.*s.o`. - - if (is_arch_wasm()) { - timings_start_section(timings, str_lit("wasm-ld")); - - #if defined(GB_SYSTEM_WINDOWS) - result = system_exec_command_line_app("wasm-ld", - "\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s", - LIT(build_context.ODIN_ROOT), - LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); - #else - result = system_exec_command_line_app("wasm-ld", - "wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s", - LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); - #endif - return result; - } - - if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { -#if defined(GB_SYSTEM_UNIX) - result = system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s", - LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); -#else - gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n", - LIT(target_os_names[build_context.metrics.os]), - LIT(target_arch_names[build_context.metrics.arch]) - ); -#endif - } else if (build_context.cross_compiling && build_context.different_os) { - gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n", - LIT(target_os_names[build_context.metrics.os]), - LIT(target_arch_names[build_context.metrics.arch]) - ); - build_context.keep_object_files = true; - } else { - #if defined(GB_SYSTEM_WINDOWS) - bool is_windows = true; - #else - bool is_windows = false; - #endif - #if defined(GB_SYSTEM_OSX) - bool is_osx = true; - #else - bool is_osx = false; - #endif - - - if (is_windows) { - String section_name = str_lit("msvc-link"); - if (build_context.use_lld) { - section_name = str_lit("lld-link"); - } - timings_start_section(timings, section_name); - - gbString lib_str = gb_string_make(heap_allocator(), ""); - defer (gb_string_free(lib_str)); - - gbString link_settings = gb_string_make_reserve(heap_allocator(), 256); - defer (gb_string_free(link_settings)); - - // Add library search paths. - if (build_context.build_paths[BuildPath_VS_LIB].basename.len > 0) { - String path = {}; - auto add_path = [&](String path) { - if (path[path.len-1] == '\\') { - path.len -= 1; - } - link_settings = gb_string_append_fmt(link_settings, " /LIBPATH:\"%.*s\"", LIT(path)); - }; - add_path(build_context.build_paths[BuildPath_Win_SDK_UM_Lib].basename); - add_path(build_context.build_paths[BuildPath_Win_SDK_UCRT_Lib].basename); - add_path(build_context.build_paths[BuildPath_VS_LIB].basename); - } - - - StringSet libs = {}; - string_set_init(&libs, 64); - defer (string_set_destroy(&libs)); - - StringSet asm_files = {}; - string_set_init(&asm_files, 64); - defer (string_set_destroy(&asm_files)); - - for (Entity *e : gen->foreign_libraries) { - GB_ASSERT(e->kind == Entity_LibraryName); - for_array(i, e->LibraryName.paths) { - String lib = string_trim_whitespace(e->LibraryName.paths[i]); - // IMPORTANT NOTE(bill): calling `string_to_lower` here is not an issue because - // we will never uses these strings afterwards - string_to_lower(&lib); - if (lib.len == 0) { - continue; - } - - if (has_asm_extension(lib)) { - if (!string_set_update(&asm_files, lib)) { - String asm_file = asm_files.entries[i].value; - String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".obj")); - - result = system_exec_command_line_app("nasm", - "\"%.*s\\bin\\nasm\\windows\\nasm.exe\" \"%.*s\" " - "-f win64 " - "-o \"%.*s\" " - "%.*s " - "", - LIT(build_context.ODIN_ROOT), LIT(asm_file), - LIT(obj_file), - LIT(build_context.extra_assembler_flags) - ); - - if (result) { - return result; - } - array_add(&gen->output_object_paths, obj_file); - } - } else { - if (!string_set_update(&libs, lib)) { - lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); - } - } - } - } - - for (Entity *e : gen->foreign_libraries) { - GB_ASSERT(e->kind == Entity_LibraryName); - if (e->LibraryName.extra_linker_flags.len != 0) { - lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(e->LibraryName.extra_linker_flags)); - } - } - - if (build_context.build_mode == BuildMode_DynamicLibrary) { - link_settings = gb_string_append_fmt(link_settings, " /DLL"); - } else { - link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup"); - } - - if (build_context.pdb_filepath != "") { - String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); - link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(pdb_path)); - } - - if (build_context.no_crt) { - link_settings = gb_string_append_fmt(link_settings, " /nodefaultlib"); - } else { - link_settings = gb_string_append_fmt(link_settings, " /defaultlib:libcmt"); - } - - if (build_context.ODIN_DEBUG) { - link_settings = gb_string_append_fmt(link_settings, " /DEBUG"); - } - - gbString object_files = gb_string_make(heap_allocator(), ""); - defer (gb_string_free(object_files)); - for (String const &object_path : gen->output_object_paths) { - object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); - } - - String vs_exe_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_VS_EXE]); - defer (gb_free(heap_allocator(), vs_exe_path.text)); - - String windows_sdk_bin_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Win_SDK_Bin_Path]); - defer (gb_free(heap_allocator(), windows_sdk_bin_path.text)); - - char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE"; - if (!build_context.use_lld) { // msvc - String res_path = {}; - defer (gb_free(heap_allocator(), res_path.text)); - if (build_context.has_resource) { - String temp_res_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RES]); - res_path = concatenate3_strings(heap_allocator(), str_lit("\""), temp_res_path, str_lit("\"")); - gb_free(heap_allocator(), temp_res_path.text); - - String rc_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RC]); - defer (gb_free(heap_allocator(), rc_path.text)); - - result = system_exec_command_line_app("msvc-link", - "\"%.*src.exe\" /nologo /fo \"%.*s\" \"%.*s\"", - LIT(windows_sdk_bin_path), - LIT(res_path), - LIT(rc_path) - ); - - if (result) { - return result; - } - } - - switch (build_context.build_mode) { - case BuildMode_Executable: - link_settings = gb_string_append_fmt(link_settings, " /NOIMPLIB /NOEXP"); - break; - } - - result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s %.*s -OUT:\"%.*s\" %s " - "/nologo /incremental:no /opt:ref /subsystem:%s " - "%.*s " - "%.*s " - "%s " - "", - LIT(vs_exe_path), object_files, LIT(res_path), LIT(output_filename), - link_settings, - subsystem_str, - LIT(build_context.link_flags), - LIT(build_context.extra_linker_flags), - lib_str - ); - if (result) { - return result; - } - } else { // lld - result = system_exec_command_line_app("msvc-lld-link", - "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s\" %s " - "/nologo /incremental:no /opt:ref /subsystem:%s " - "%.*s " - "%.*s " - "%s " - "", - LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), - link_settings, - subsystem_str, - LIT(build_context.link_flags), - LIT(build_context.extra_linker_flags), - lib_str - ); - - if (result) { - return result; - } - } - } else { - timings_start_section(timings, str_lit("ld-link")); - - // NOTE(vassvik): get cwd, for used for local shared libs linking, since those have to be relative to the exe - char cwd[256]; - #if !defined(GB_SYSTEM_WINDOWS) - getcwd(&cwd[0], 256); - #endif - //printf("%s\n", cwd); - - // NOTE(vassvik): needs to add the root to the library search paths, so that the full filenames of the library - // files can be passed with -l: - gbString lib_str = gb_string_make(heap_allocator(), "-L/"); - defer (gb_string_free(lib_str)); - - StringSet libs = {}; - string_set_init(&libs, 64); - defer (string_set_destroy(&libs)); - - for (Entity *e : gen->foreign_libraries) { - GB_ASSERT(e->kind == Entity_LibraryName); - for (String lib : e->LibraryName.paths) { - lib = string_trim_whitespace(lib); - if (lib.len == 0) { - continue; - } - if (string_set_update(&libs, lib)) { - continue; - } - - // NOTE(zangent): Sometimes, you have to use -framework on MacOS. - // This allows you to specify '-f' in a #foreign_system_library, - // without having to implement any new syntax specifically for MacOS. - if (build_context.metrics.os == TargetOs_darwin) { - if (string_ends_with(lib, str_lit(".framework"))) { - // framework thingie - String lib_name = lib; - lib_name = remove_extension_from_path(lib_name); - lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name)); - } else if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o")) || string_ends_with(lib, str_lit(".dylib"))) { - // For: - // object - // dynamic lib - // static libs, absolute full path relative to the file in which the lib was imported from - lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib)); - } else { - // dynamic or static system lib, just link regularly searching system library paths - lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib)); - } - } else { - // NOTE(vassvik): static libraries (.a files) in linux can be linked to directly using the full path, - // since those are statically linked to at link time. shared libraries (.so) has to be - // available at runtime wherever the executable is run, so we make require those to be - // local to the executable (unless the system collection is used, in which case we search - // the system library paths for the library file). - if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o"))) { - // static libs and object files, absolute full path relative to the file in which the lib was imported from - lib_str = gb_string_append_fmt(lib_str, " -l:\"%.*s\" ", LIT(lib)); - } else if (string_ends_with(lib, str_lit(".so"))) { - // dynamic lib, relative path to executable - // NOTE(vassvik): it is the user's responsibility to make sure the shared library files are visible - // at runtime to the executable - lib_str = gb_string_append_fmt(lib_str, " -l:\"%s/%.*s\" ", cwd, LIT(lib)); - } else { - // dynamic or static system lib, just link regularly searching system library paths - lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib)); - } - } - } - } - - for (Entity *e : gen->foreign_libraries) { - GB_ASSERT(e->kind == Entity_LibraryName); - if (e->LibraryName.extra_linker_flags.len != 0) { - lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(e->LibraryName.extra_linker_flags)); - } - } - - gbString object_files = gb_string_make(heap_allocator(), ""); - defer (gb_string_free(object_files)); - for (String object_path : gen->output_object_paths) { - object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); - } - - gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); - - if (build_context.no_crt) { - link_settings = gb_string_append_fmt(link_settings, "-nostdlib "); - } - - // NOTE(dweiler): We use clang as a frontend for the linker as there are - // other runtime and compiler support libraries that need to be linked in - // very specific orders such as libgcc_s, ld-linux-so, unwind, etc. - // These are not always typically inside /lib, /lib64, or /usr versions - // of that, e.g libgcc.a is in /usr/lib/gcc/{version}, and can vary on - // the distribution of Linux even. The gcc or clang specs is the only - // reliable way to query this information to call ld directly. - if (build_context.build_mode == BuildMode_DynamicLibrary) { - // NOTE(dweiler): Let the frontend know we're building a shared library - // so it doesn't generate symbols which cannot be relocated. - link_settings = gb_string_appendc(link_settings, "-shared "); - - // NOTE(dweiler): _odin_entry_point must be called at initialization - // time of the shared object, similarly, _odin_exit_point must be called - // at deinitialization. We can pass both -init and -fini to the linker by - // using a comma separated list of arguments to -Wl. - // - // This previously used ld but ld cannot actually build a shared library - // correctly this way since all the other dependencies provided implicitly - // by the compiler frontend are still needed and most of the command - // line arguments prepared previously are incompatible with ld. - if (build_context.metrics.os == TargetOs_darwin) { - link_settings = gb_string_appendc(link_settings, "-Wl,-init,'__odin_entry_point' "); - // NOTE(weshardee): __odin_exit_point should also be added, but -fini - // does not exist on MacOS - } else { - link_settings = gb_string_appendc(link_settings, "-Wl,-init,'_odin_entry_point' "); - link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' "); - } - - } else if (build_context.metrics.os != TargetOs_openbsd) { - // OpenBSD defaults to PIE executable. do not pass -no-pie for it. - link_settings = gb_string_appendc(link_settings, "-no-pie "); - } - - gbString platform_lib_str = gb_string_make(heap_allocator(), ""); - defer (gb_string_free(platform_lib_str)); - if (build_context.metrics.os == TargetOs_darwin) { - platform_lib_str = gb_string_appendc(platform_lib_str, "-lSystem -lm -Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib"); - } else { - platform_lib_str = gb_string_appendc(platform_lib_str, "-lc -lm"); - } - - if (build_context.metrics.os == TargetOs_darwin) { - // This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit. - if (build_context.minimum_os_version_string.len) { - link_settings = gb_string_append_fmt(link_settings, " -mmacosx-version-min=%.*s ", LIT(build_context.minimum_os_version_string)); - } else if (build_context.metrics.arch == TargetArch_arm64) { - link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=12.0.0 "); - } else { - link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=10.12.0 "); - } - // This points the linker to where the entry point is - link_settings = gb_string_appendc(link_settings, " -e _main "); - } - - gbString link_command_line = gb_string_make(heap_allocator(), "clang -Wno-unused-command-line-argument "); - defer (gb_string_free(link_command_line)); - - link_command_line = gb_string_appendc(link_command_line, object_files); - link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s\" ", LIT(output_filename)); - link_command_line = gb_string_append_fmt(link_command_line, " %s ", platform_lib_str); - link_command_line = gb_string_append_fmt(link_command_line, " %s ", lib_str); - link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.link_flags)); - link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.extra_linker_flags)); - link_command_line = gb_string_append_fmt(link_command_line, " %s ", link_settings); - - result = system_exec_command_line_app("ld-link", link_command_line); - - if (result) { - return result; - } - - if (is_osx && build_context.ODIN_DEBUG) { - // NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe - // to the symbols in the object file - result = system_exec_command_line_app("dsymutil", "dsymutil %.*s", LIT(output_filename)); - - if (result) { - return result; - } - } - } - } - - return result; -} - gb_internal Array<String> setup_args(int argc, char const **argv) { gbAllocator a = heap_allocator(); @@ -653,8 +248,16 @@ enum BuildFlagKind { BuildFlag_UseSeparateModules, BuildFlag_NoThreadedChecker, BuildFlag_ShowDebugMessages, + BuildFlag_Vet, + BuildFlag_VetShadowing, + BuildFlag_VetUnused, + BuildFlag_VetUsingStmt, + BuildFlag_VetUsingParam, + BuildFlag_VetStyle, + BuildFlag_VetSemicolon, BuildFlag_VetExtra, + BuildFlag_IgnoreUnknownAttributes, BuildFlag_ExtraLinkerFlags, BuildFlag_ExtraAssemblerFlags, @@ -671,7 +274,6 @@ enum BuildFlagKind { BuildFlag_DisallowDo, BuildFlag_DefaultToNilAllocator, BuildFlag_StrictStyle, - BuildFlag_StrictStyleInitOnly, BuildFlag_ForeignErrorProcedures, BuildFlag_NoRTTI, BuildFlag_DynamicMapCalls, @@ -695,6 +297,8 @@ enum BuildFlagKind { BuildFlag_InternalIgnoreLazy, BuildFlag_InternalIgnoreLLVMBuild, + BuildFlag_Tilde, + #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, BuildFlag_ResourceFile, @@ -830,8 +434,16 @@ gb_internal bool parse_build_flags(Array<String> args) { add_flag(&build_flags, BuildFlag_UseSeparateModules, str_lit("use-separate-modules"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_NoThreadedChecker, str_lit("no-threaded-checker"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ShowDebugMessages, str_lit("show-debug-messages"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetUnused, str_lit("vet-unused"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetShadowing, str_lit("vet-shadowing"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetUsingStmt, str_lit("vet-using-stmt"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetUsingParam, str_lit("vet-using-param"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetStyle, str_lit("vet-style"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetSemicolon, str_lit("vet-semicolon"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetExtra, str_lit("vet-extra"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags, str_lit("extra-assembler-flags"), BuildFlagParam_String, Command__does_build); @@ -847,7 +459,6 @@ gb_internal bool parse_build_flags(Array<String> args) { add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_StrictStyle, str_lit("strict-style"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_StrictStyleInitOnly, str_lit("strict-style-init-only"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ForeignErrorProcedures, str_lit("foreign-error-procedures"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoRTTI, str_lit("no-rtti"), BuildFlagParam_None, Command__does_check); @@ -869,6 +480,10 @@ gb_internal bool parse_build_flags(Array<String> args) { add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_InternalIgnoreLLVMBuild, str_lit("internal-ignore-llvm-build"),BuildFlagParam_None, Command_all); +#if ALLOW_TILDE + add_flag(&build_flags, BuildFlag_Tilde, str_lit("tilde"), BuildFlagParam_None, Command__does_build); +#endif + #if defined(GB_SYSTEM_WINDOWS) add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_ResourceFile, str_lit("resource"), BuildFlagParam_String, Command__does_build); @@ -1362,13 +977,25 @@ gb_internal bool parse_build_flags(Array<String> args) { build_context.show_debug_messages = true; break; case BuildFlag_Vet: - build_context.vet = true; + if (build_context.vet_flags & VetFlag_Extra) { + build_context.vet_flags |= VetFlag_All; + } else { + build_context.vet_flags &= ~VetFlag_Extra; + build_context.vet_flags |= VetFlag_All; + } break; - case BuildFlag_VetExtra: { - build_context.vet = true; - build_context.vet_extra = true; + + case BuildFlag_VetUnused: build_context.vet_flags |= VetFlag_Unused; break; + case BuildFlag_VetShadowing: build_context.vet_flags |= VetFlag_Shadowing; break; + case BuildFlag_VetUsingStmt: build_context.vet_flags |= VetFlag_UsingStmt; break; + case BuildFlag_VetUsingParam: build_context.vet_flags |= VetFlag_UsingParam; break; + case BuildFlag_VetStyle: build_context.vet_flags |= VetFlag_Style; break; + case BuildFlag_VetSemicolon: build_context.vet_flags |= VetFlag_Semicolon; break; + + case BuildFlag_VetExtra: + build_context.vet_flags = VetFlag_All | VetFlag_Extra; break; - } + case BuildFlag_IgnoreUnknownAttributes: build_context.ignore_unknown_attributes = true; break; @@ -1456,20 +1083,9 @@ gb_internal bool parse_build_flags(Array<String> args) { case BuildFlag_ForeignErrorProcedures: build_context.ODIN_FOREIGN_ERROR_PROCEDURES = true; break; - case BuildFlag_StrictStyle: { - if (build_context.strict_style_init_only) { - gb_printf_err("-strict-style and -strict-style-init-only cannot be used together\n"); - } + case BuildFlag_StrictStyle: build_context.strict_style = true; break; - } - case BuildFlag_StrictStyleInitOnly: { - if (build_context.strict_style) { - gb_printf_err("-strict-style and -strict-style-init-only cannot be used together\n"); - } - build_context.strict_style_init_only = true; - break; - } case BuildFlag_Short: build_context.cmd_doc_flags |= CmdDocFlag_Short; break; @@ -1536,6 +1152,10 @@ gb_internal bool parse_build_flags(Array<String> args) { case BuildFlag_InternalIgnoreLLVMBuild: build_context.ignore_llvm_build = true; break; + case BuildFlag_Tilde: + build_context.tilde_backend = true; + break; + #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: { GB_ASSERT(value.kind == ExactValue_Invalid); @@ -1572,7 +1192,7 @@ gb_internal bool parse_build_flags(Array<String> args) { if (path_is_directory(path)) { gb_printf_err("Invalid -pdb-name path. %.*s, is a directory.\n", LIT(path)); bad_flags = true; - break; + break; } // #if defined(GB_SYSTEM_WINDOWS) // String ext = path_extension(path); @@ -2005,6 +1625,10 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(2, "Shows an advanced overview of the timings of different stages within the compiler in milliseconds"); print_usage_line(0, ""); + print_usage_line(1, "-show-system-calls"); + print_usage_line(2, "Prints the whole command and arguments for calls to external tools like linker and assembler"); + print_usage_line(0, ""); + print_usage_line(1, "-export-timings:<format>"); print_usage_line(2, "Export timings to one of a few formats. Requires `-show-timings` or `-show-more-timings`"); print_usage_line(2, "Available options:"); @@ -2114,29 +1738,55 @@ gb_internal void print_show_help(String const arg0, String const &command) { } if (check) { - #if defined(GB_SYSTEM_WINDOWS) print_usage_line(1, "-no-threaded-checker"); print_usage_line(2, "Disabled multithreading in the semantic checker stage"); print_usage_line(0, ""); - #else - print_usage_line(1, "-threaded-checker"); - print_usage_line(1, "[EXPERIMENTAL]"); - print_usage_line(2, "Multithread the semantic checker stage"); - print_usage_line(0, ""); - #endif + } + if (check) { print_usage_line(1, "-vet"); print_usage_line(2, "Do extra checks on the code"); print_usage_line(2, "Extra checks include:"); - print_usage_line(3, "Variable shadowing within procedures"); - print_usage_line(3, "Unused declarations"); + print_usage_line(2, "-vet-unused"); + print_usage_line(2, "-vet-shadowing"); + print_usage_line(2, "-vet-using-stmt"); + print_usage_line(0, ""); + + print_usage_line(1, "-vet-unused"); + print_usage_line(2, "Checks for unused declarations"); + print_usage_line(0, ""); + + print_usage_line(1, "-vet-shadowing"); + print_usage_line(2, "Checks for variable shadowing within procedures"); + print_usage_line(0, ""); + + print_usage_line(1, "-vet-using-stmt"); + print_usage_line(2, "Checks for the use of 'using' as a statement"); + print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring"); + print_usage_line(0, ""); + + print_usage_line(1, "-vet-using-param"); + print_usage_line(2, "Checks for the use of 'using' on procedure parameters"); + print_usage_line(2, "'using' is considered bad practice outside of immediate refactoring"); + print_usage_line(0, ""); + + print_usage_line(1, "-vet-style"); + print_usage_line(2, "Errs on missing trailing commas followed by a newline"); + print_usage_line(2, "Errs on deprecated syntax"); + print_usage_line(2, "Does not err on unneeded tokens (unlike -strict-style)"); + print_usage_line(0, ""); + + print_usage_line(1, "-vet-semicolon"); + print_usage_line(2, "Errs on unneeded semicolons"); print_usage_line(0, ""); print_usage_line(1, "-vet-extra"); print_usage_line(2, "Do even more checks than standard vet on the code"); print_usage_line(2, "To treat the extra warnings as errors, use -warnings-as-errors"); print_usage_line(0, ""); + } + if (check) { print_usage_line(1, "-ignore-unknown-attributes"); print_usage_line(2, "Ignores unknown attributes"); print_usage_line(2, "This can be used with metaprogramming tools"); @@ -2206,10 +1856,8 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-strict-style"); print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons"); - print_usage_line(0, ""); - - print_usage_line(1, "-strict-style-init-only"); - print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons, only on the initial project"); + print_usage_line(2, "Errs on missing trailing commas followed by a newline"); + print_usage_line(2, "Errs on deprecated syntax"); print_usage_line(0, ""); print_usage_line(1, "-ignore-warnings"); @@ -2347,6 +1995,8 @@ gb_internal void print_show_unused(Checker *c) { } gb_internal bool check_env(void) { + TIME_SECTION("init check env"); + gbAllocator a = heap_allocator(); char const *odin_root = gb_get_env("ODIN_ROOT", a); defer (gb_free(a, cast(void *)odin_root)); @@ -2548,6 +2198,7 @@ gb_internal int strip_semicolons(Parser *parser) { } gb_internal void init_terminal(void) { + TIME_SECTION("init terminal"); build_context.has_ansi_terminal_colours = false; gbAllocator a = heap_allocator(); @@ -2614,11 +2265,13 @@ int main(int arg_count, char const **arg_ptr) { return 1; } + TIME_SECTION("init default library collections"); array_init(&library_collections, heap_allocator()); // NOTE(bill): 'core' cannot be (re)defined by the user add_library_collection(str_lit("core"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("core"))); add_library_collection(str_lit("vendor"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("vendor"))); + TIME_SECTION("init args"); map_init(&build_context.defined_values); build_context.extra_packages.allocator = heap_allocator(); string_set_init(&build_context.test_names); @@ -2814,12 +2467,14 @@ int main(int arg_count, char const **arg_ptr) { for_array(i, build_context.build_paths) { String build_path = path_to_string(heap_allocator(), build_context.build_paths[i]); debugf("build_paths[%ld]: %.*s\n", i, LIT(build_path)); - } + } } + TIME_SECTION("init thread pool"); init_global_thread_pool(); defer (thread_pool_destroy(&global_thread_pool)); + TIME_SECTION("init universal"); init_universal(); // TODO(bill): prevent compiling without a linker @@ -2882,16 +2537,18 @@ int main(int arg_count, char const **arg_ptr) { return 0; } - MAIN_TIME_SECTION("LLVM API Code Gen"); - lbGenerator *gen = gb_alloc_item(permanent_allocator(), lbGenerator); - if (!lb_init_generator(gen, checker)) { - return 1; - } - if (lb_generate_code(gen)) { +#if ALLOW_TILDE + if (build_context.tilde_backend) { + LinkerData linker_data = {}; + MAIN_TIME_SECTION("Tilde Code Gen"); + if (!cg_generate_code(checker, &linker_data)) { + return 1; + } + switch (build_context.build_mode) { case BuildMode_Executable: case BuildMode_DynamicLibrary: - i32 result = linker_stage(gen); + i32 result = linker_stage(&linker_data); if (result) { if (build_context.show_timings) { show_timings(checker, &global_timings); @@ -2900,9 +2557,31 @@ int main(int arg_count, char const **arg_ptr) { } break; } - } + } else +#endif + { + MAIN_TIME_SECTION("LLVM API Code Gen"); + lbGenerator *gen = gb_alloc_item(permanent_allocator(), lbGenerator); + if (!lb_init_generator(gen, checker)) { + return 1; + } + if (lb_generate_code(gen)) { + switch (build_context.build_mode) { + case BuildMode_Executable: + case BuildMode_DynamicLibrary: + i32 result = linker_stage(gen); + if (result) { + if (build_context.show_timings) { + show_timings(checker, &global_timings); + } + return result; + } + break; + } + } - remove_temp_files(gen); + remove_temp_files(gen); + } if (build_context.show_timings) { show_timings(checker, &global_timings); |