From 7694a89d381c14bbefb54ce2589d7e291b79dfe4 Mon Sep 17 00:00:00 2001 From: Platin21 Date: Sat, 31 Oct 2020 22:05:40 +0100 Subject: Fix for local/lib linking from brew for macOS --- src/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 149c1522d..154be362f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -431,19 +431,19 @@ i32 linker_stage(lbGenerator *gen) { " -e _main " #endif , linker, object_files, LIT(output_base), LIT(output_ext), - lib_str, #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk", + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -L/usr/local/lib", #else "-lc -lm", #endif + lib_str, LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); if (exit_code != 0) { return exit_code; } - + #if defined(GB_SYSTEM_OSX) if (build_context.ODIN_DEBUG) { // NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe @@ -2221,7 +2221,7 @@ int main(int arg_count, char const **arg_ptr) { , linker, LIT(output_base), LIT(output_base), LIT(output_ext), lib_str, #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk", + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", #else "-lc -lm", #endif -- cgit v1.2.3 From f3108493fbfc89a80643dba969828b7a01acac4e Mon Sep 17 00:00:00 2001 From: Platin21 Date: Sat, 31 Oct 2020 22:12:50 +0100 Subject: Combines all link-able types to a single if and adds .o for linking --- src/main.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 154be362f..7e043b8d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -341,12 +341,15 @@ i32 linker_stage(lbGenerator *gen) { 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"))) { + } 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 if (string_ends_with(lib, str_lit(".dylib"))) { - // dynamic lib - 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)); @@ -2136,13 +2139,16 @@ int main(int arg_count, char const **arg_ptr) { 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"))) { - // 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 if (string_ends_with(lib, str_lit(".dylib"))) { - // dynamic lib - lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib)); - } else { + } 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)); } -- cgit v1.2.3 From 8158239d76e3407f7405e47b222ffb2f1c5aea31 Mon Sep 17 00:00:00 2001 From: Platin21 Date: Sat, 31 Oct 2020 22:15:16 +0100 Subject: Sets llvm api back to use the generic sdk link --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 7e043b8d4..c50be6136 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -435,7 +435,7 @@ i32 linker_stage(lbGenerator *gen) { #endif , linker, object_files, LIT(output_base), LIT(output_ext), #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -L/usr/local/lib", + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", #else "-lc -lm", #endif -- cgit v1.2.3 From fc7c0ca3b0413a90fabd5d41a43bff227e61477f Mon Sep 17 00:00:00 2001 From: Platin21 Date: Sat, 31 Oct 2020 22:29:02 +0100 Subject: Changed tab width was on 2 now 4 --- src/main.cpp | 56 +++++++++++++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 31 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index c50be6136..b30395941 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -341,16 +341,13 @@ i32 linker_stage(lbGenerator *gen) { 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 { + } 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)); } @@ -434,12 +431,12 @@ i32 linker_stage(lbGenerator *gen) { " -e _main " #endif , linker, object_files, LIT(output_base), LIT(output_ext), - #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", - #else - "-lc -lm", - #endif - lib_str, + #if defined(GB_SYSTEM_OSX) + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", + #else + "-lc -lm", + #endif + lib_str, LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); @@ -2139,16 +2136,13 @@ int main(int arg_count, char const **arg_ptr) { 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 { + } 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)); } @@ -2226,11 +2220,11 @@ int main(int arg_count, char const **arg_ptr) { #endif , linker, LIT(output_base), LIT(output_base), LIT(output_ext), lib_str, - #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", - #else - "-lc -lm", - #endif + #if defined(GB_SYSTEM_OSX) + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", + #else + "-lc -lm", + #endif LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); -- cgit v1.2.3 From f29f7351e983d29037df9c016ab3633ffc6ebae2 Mon Sep 17 00:00:00 2001 From: Platin21 Date: Sat, 31 Oct 2020 22:30:03 +0100 Subject: Revert "Changed tab width was on 2 now 4" This reverts commit fc7c0ca3b0413a90fabd5d41a43bff227e61477f. --- src/main.cpp | 56 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 25 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index b30395941..c50be6136 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -341,13 +341,16 @@ i32 linker_stage(lbGenerator *gen) { 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 { + } 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)); } @@ -431,12 +434,12 @@ i32 linker_stage(lbGenerator *gen) { " -e _main " #endif , linker, object_files, LIT(output_base), LIT(output_ext), - #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", - #else - "-lc -lm", - #endif - lib_str, + #if defined(GB_SYSTEM_OSX) + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", + #else + "-lc -lm", + #endif + lib_str, LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); @@ -2136,13 +2139,16 @@ int main(int arg_count, char const **arg_ptr) { 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 { + } 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)); } @@ -2220,11 +2226,11 @@ int main(int arg_count, char const **arg_ptr) { #endif , linker, LIT(output_base), LIT(output_base), LIT(output_ext), lib_str, - #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", - #else - "-lc -lm", - #endif + #if defined(GB_SYSTEM_OSX) + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", + #else + "-lc -lm", + #endif LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); -- cgit v1.2.3 From 8c46582667bc211df6e61aa676e17e128f89d568 Mon Sep 17 00:00:00 2001 From: Platin21 Date: Sat, 31 Oct 2020 22:37:11 +0100 Subject: Fixes text layout now via GitHub --- src/main.cpp | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index c50be6136..a7b951b67 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -341,13 +341,10 @@ i32 linker_stage(lbGenerator *gen) { 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 + } 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 { @@ -434,12 +431,12 @@ i32 linker_stage(lbGenerator *gen) { " -e _main " #endif , linker, object_files, LIT(output_base), LIT(output_ext), - #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", - #else - "-lc -lm", - #endif - lib_str, + #if defined(GB_SYSTEM_OSX) + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", + #else + "-lc -lm", + #endif + lib_str, LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); @@ -2139,13 +2136,11 @@ int main(int arg_count, char const **arg_ptr) { 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 + + } 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 { @@ -2226,11 +2221,11 @@ int main(int arg_count, char const **arg_ptr) { #endif , linker, LIT(output_base), LIT(output_base), LIT(output_ext), lib_str, - #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", - #else - "-lc -lm", - #endif + #if defined(GB_SYSTEM_OSX) + "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", + #else + "-lc -lm", + #endif LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); -- cgit v1.2.3 From 140bb3ebfcfa7579e53e836c3fb75792efbed078 Mon Sep 17 00:00:00 2001 From: Tetralux Date: Fri, 6 Nov 2020 05:43:13 +0000 Subject: Fix -build-mode:shared type table on Unix Fixes #527. Previously on Linux, '__$startup_runtime', the procedure that initializes the type table for runtime typeids, was NOT called when a shared library was loaded by the dynamic loader. This caused the library to not have its type table populated, which caused an assert to fail if you tried to use runtime typeids - like core:fmt, for example. This commit fixes this by calling ld instead of clang, when building a shared library, so that we can pass "-init '__$startup_runtime'" to it, when building a shared library. Try as I might, I could not get clang to correctly pass through the linker flags that I wanted. --- src/main.cpp | 82 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 37 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index a7b951b67..1ae0e7d97 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -342,9 +342,9 @@ i32 linker_stage(lbGenerator *gen) { 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 + // 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 { @@ -382,20 +382,33 @@ i32 linker_stage(lbGenerator *gen) { // Unlike the Win32 linker code, the output_ext includes the dot, because // typically executable files on *NIX systems don't have extensions. String output_ext = {}; - char const *link_settings = ""; + gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); char const *linker; if (build_context.build_mode == BuildMode_DynamicLibrary) { + // NOTE(tetra, 2020-11-06): __$startup_runtime must be called at DLL load time. + // Clang, for some reason, won't let us pass the '-init' flag that lets us do this, + // so use ld instead. + // :UseLDForShared + linker = "ld"; + link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' "); // Shared libraries are .dylib on MacOS and .so on Linux. #if defined(GB_SYSTEM_OSX) output_ext = STR_LIT(".dylib"); - link_settings = "-dylib -dynamic"; + link_settings = gb_string_appendc(link_settings, "-dylib -dynamic "); #else output_ext = STR_LIT(".so"); - link_settings = "-shared"; + link_settings = gb_string_appendc(link_settings, "-shared "); #endif } else { - // TODO: Do I need anything here? - link_settings = ""; + #if defined(GB_SYSTEM_OSX) + linker = "ld"; + #else + // TODO(zangent): Figure out how to make ld work on Linux. + // It probably has to do with including the entire CRT, but + // that's quite a complicated issue to solve while remaining distro-agnostic. + // Clang can figure out linker flags for us, and that's good enough _for now_. + linker = "clang -Wno-unused-command-line-argument"; + #endif } if (build_context.out_filepath.len > 0) { @@ -406,16 +419,6 @@ i32 linker_stage(lbGenerator *gen) { } } - #if defined(GB_SYSTEM_OSX) - linker = "ld"; - #else - // TODO(zangent): Figure out how to make ld work on Linux. - // It probably has to do with including the entire CRT, but - // that's quite a complicated issue to solve while remaining distro-agnostic. - // Clang can figure out linker flags for us, and that's good enough _for now_. - linker = "clang -Wno-unused-command-line-argument"; - #endif - exit_code = system_exec_command_line_app("ld-link", "%s %s -o \"%.*s%.*s\" %s " " %s " @@ -443,7 +446,7 @@ i32 linker_stage(lbGenerator *gen) { if (exit_code != 0) { return exit_code; } - + #if defined(GB_SYSTEM_OSX) if (build_context.ODIN_DEBUG) { // NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe @@ -2136,11 +2139,11 @@ int main(int arg_count, char const **arg_ptr) { 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 + // 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 { @@ -2171,22 +2174,36 @@ int main(int arg_count, char const **arg_ptr) { // Unlike the Win32 linker code, the output_ext includes the dot, because // typically executable files on *NIX systems don't have extensions. String output_ext = {}; - char const *link_settings = ""; + gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); char const *linker; if (build_context.build_mode == BuildMode_DynamicLibrary) { + // NOTE(tetra, 2020-11-06): __$startup_runtime must be called at DLL load time. + // Clang, for some reason, won't let us pass the '-init' flag that lets us do this, + // so use ld instead. + // :UseLDForShared + linker = "ld"; + link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' "); // Shared libraries are .dylib on MacOS and .so on Linux. #if defined(GB_SYSTEM_OSX) output_ext = STR_LIT(".dylib"); - link_settings = "-dylib -dynamic"; + link_settings = gb_string_appendc(link_settings, "-dylib -dynamic "); #else output_ext = STR_LIT(".so"); - link_settings = "-shared"; + link_settings = gb_string_appendc(link_settings, "-shared "); #endif } else { - // TODO: Do I need anything here? - link_settings = ""; + #if defined(GB_SYSTEM_OSX) + linker = "ld"; + #else + // TODO(zangent): Figure out how to make ld work on Linux. + // It probably has to do with including the entire CRT, but + // that's quite a complicated issue to solve while remaining distro-agnostic. + // Clang can figure out linker flags for us, and that's good enough _for now_. + linker = "clang -Wno-unused-command-line-argument"; + #endif } + if (build_context.out_filepath.len > 0) { //NOTE(thebirk): We have a custom -out arguments, so we should use the extension from that isize pos = string_extension_position(build_context.out_filepath); @@ -2195,15 +2212,6 @@ int main(int arg_count, char const **arg_ptr) { } } - #if defined(GB_SYSTEM_OSX) - linker = "ld"; - #else - // TODO(zangent): Figure out how to make ld work on Linux. - // It probably has to do with including the entire CRT, but - // that's quite a complicated issue to solve while remaining distro-agnostic. - // Clang can figure out linker flags for us, and that's good enough _for now_. - linker = "clang -Wno-unused-command-line-argument"; - #endif exit_code = system_exec_command_line_app("ld-link", "%s \"%.*s.o\" -o \"%.*s%.*s\" %s " -- cgit v1.2.3 From 301e1d2ff3954453213aefa271263cd2644849f1 Mon Sep 17 00:00:00 2001 From: F0x1fy Date: Tue, 10 Nov 2020 09:50:53 -0700 Subject: Added -no-entry-point flag and relevant check. --- src/build_settings.cpp | 1 + src/checker.cpp | 2 +- src/main.cpp | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index ed259f7cd..4f06c2913 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -151,6 +151,7 @@ struct BuildContext { bool no_dynamic_literals; bool no_output_files; bool no_crt; + bool no_entry_point; bool use_lld; bool vet; bool cross_compiling; diff --git a/src/checker.cpp b/src/checker.cpp index 5c93e12b6..ac324fffa 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4572,7 +4572,7 @@ void check_parsed_files(Checker *c) { TIME_SECTION("check entry point"); - if (build_context.build_mode == BuildMode_Executable) { + if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point) { Scope *s = c->info.init_scope; GB_ASSERT(s != nullptr); GB_ASSERT(s->flags&ScopeFlag_Init); diff --git a/src/main.cpp b/src/main.cpp index 1ae0e7d97..68d4a03c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -581,6 +581,7 @@ enum BuildFlagKind { BuildFlag_NoBoundsCheck, BuildFlag_NoDynamicLiterals, BuildFlag_NoCRT, + BuildFlag_NoEntryPoint, BuildFlag_UseLLD, BuildFlag_Vet, BuildFlag_UseLLVMApi, @@ -591,6 +592,7 @@ enum BuildFlagKind { BuildFlag_DisallowDo, BuildFlag_DefaultToNilAllocator, + BuildFlag_Compact, BuildFlag_GlobalDefinitions, BuildFlag_GoToDefinitions, @@ -680,6 +682,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None); @@ -1095,6 +1098,10 @@ bool parse_build_flags(Array args) { build_context.no_crt = true; break; + case BuildFlag_NoEntryPoint: + build_context.no_entry_point = true; + break; + case BuildFlag_UseLLD: build_context.use_lld = true; break; -- cgit v1.2.3 From 3bed5fad77e8dcd42d7eab40d9c7d50ce4cc47c4 Mon Sep 17 00:00:00 2001 From: F0x1fy Date: Tue, 10 Nov 2020 09:55:00 -0700 Subject: Removed unnecessary newline from previous commit. --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 68d4a03c6..5757cdd79 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -592,7 +592,6 @@ enum BuildFlagKind { BuildFlag_DisallowDo, BuildFlag_DefaultToNilAllocator, - BuildFlag_Compact, BuildFlag_GlobalDefinitions, BuildFlag_GoToDefinitions, -- cgit v1.2.3 From 6b6f1a5283c90f187e9ffc7feeda2dad6a3a5c8d Mon Sep 17 00:00:00 2001 From: F0x1fy Date: Tue, 10 Nov 2020 09:56:16 -0700 Subject: For the sake of consistency, fixed the placement of the -no-entry-point flag check. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 5757cdd79..3717a4147 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -681,8 +681,8 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None); -- cgit v1.2.3 From 3c1c10a1785a97831a69fb6d94356d5cc4989bd6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 Nov 2020 18:08:52 +0000 Subject: Begin clarifying allocation patterns by changing from `heap_allocator` to specific arenas --- src/checker.cpp | 4 +- src/checker.hpp | 2 - src/common.cpp | 48 +++++++-- src/entity.cpp | 2 +- src/llvm_abi.cpp | 7 +- src/llvm_backend.cpp | 279 +++++++++++++++++++++------------------------------ src/main.cpp | 16 ++- src/parser.cpp | 43 ++++---- src/parser.hpp | 1 + src/types.cpp | 8 +- 10 files changed, 209 insertions(+), 201 deletions(-) (limited to 'src/main.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index fe669ab8c..a07a3ffbe 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -690,8 +690,10 @@ void add_global_type_entity(String name, Type *type) { void init_universal(void) { BuildContext *bc = &build_context; + // NOTE(bill): No need to free these - gbAllocator a = heap_allocator(); + // gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); builtin_pkg = gb_alloc_item(a, AstPackage); builtin_pkg->name = str_lit("builtin"); diff --git a/src/checker.hpp b/src/checker.hpp index 3d21a4cec..88e9451ee 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -337,8 +337,6 @@ struct Checker { - - gb_global AstPackage *builtin_pkg = nullptr; gb_global AstPackage *intrinsics_pkg = nullptr; gb_global AstPackage *config_pkg = nullptr; diff --git a/src/common.cpp b/src/common.cpp index 350127e1e..567655c04 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -373,8 +373,8 @@ typedef struct Arena { gbAllocator backing; isize block_size; gbMutex mutex; - isize total_used; + bool use_mutex; } Arena; #define ARENA_MIN_ALIGNMENT 16 @@ -388,8 +388,9 @@ void arena_init(Arena *arena, gbAllocator backing, isize block_size=ARENA_DEFAUL } void arena_grow(Arena *arena, isize min_size) { - // gb_mutex_lock(&arena->mutex); - // defer (gb_mutex_unlock(&arena->mutex)); + if (arena->use_mutex) { + gb_mutex_lock(&arena->mutex); + } isize size = gb_max(arena->block_size, min_size); size = ALIGN_UP(size, ARENA_MIN_ALIGNMENT); @@ -399,11 +400,16 @@ void arena_grow(Arena *arena, isize min_size) { GB_ASSERT(arena->ptr == ALIGN_DOWN_PTR(arena->ptr, ARENA_MIN_ALIGNMENT)); arena->end = arena->ptr + size; array_add(&arena->blocks, arena->ptr); + + if (arena->use_mutex) { + gb_mutex_unlock(&arena->mutex); + } } void *arena_alloc(Arena *arena, isize size, isize alignment) { - // gb_mutex_lock(&arena->mutex); - // defer (gb_mutex_unlock(&arena->mutex)); + if (arena->use_mutex) { + gb_mutex_lock(&arena->mutex); + } arena->total_used += size; @@ -419,12 +425,17 @@ void *arena_alloc(Arena *arena, isize size, isize alignment) { GB_ASSERT(arena->ptr <= arena->end); GB_ASSERT(ptr == ALIGN_DOWN_PTR(ptr, align)); // zero_size(ptr, size); + + if (arena->use_mutex) { + gb_mutex_unlock(&arena->mutex); + } return ptr; } void arena_free_all(Arena *arena) { - // gb_mutex_lock(&arena->mutex); - // defer (gb_mutex_unlock(&arena->mutex)); + if (arena->use_mutex) { + gb_mutex_lock(&arena->mutex); + } for_array(i, arena->blocks) { gb_free(arena->backing, arena->blocks[i]); @@ -432,6 +443,10 @@ void arena_free_all(Arena *arena) { array_clear(&arena->blocks); arena->ptr = nullptr; arena->end = nullptr; + + if (arena->use_mutex) { + gb_mutex_unlock(&arena->mutex); + } } @@ -460,7 +475,14 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) { // GB_PANIC("gbAllocation_Free not supported"); break; case gbAllocation_Resize: - GB_PANIC("gbAllocation_Resize: not supported"); + if (size == 0) { + ptr = nullptr; + } else if (size <= old_size) { + ptr = old_memory; + } else { + ptr = arena_alloc(arena, size, alignment); + gb_memmove(ptr, old_memory, old_size); + } break; case gbAllocation_FreeAll: arena_free_all(arena); @@ -472,6 +494,16 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) { +gb_global Arena permanent_arena = {}; +gb_global Arena temporary_arena = {}; + +gbAllocator permanent_allocator() { + return arena_allocator(&permanent_arena); +} +gbAllocator temporary_allocator() { + return arena_allocator(&temporary_arena); +} + diff --git a/src/entity.cpp b/src/entity.cpp index a9d598735..708b0862c 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -220,7 +220,7 @@ bool entity_has_deferred_procedure(Entity *e) { gb_global u64 global_entity_id = 0; Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Type *type) { - gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); Entity *entity = gb_alloc_item(a, Entity); entity->kind = kind; entity->state = EntityState_Unresolved; diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 79f7948a3..f0422e0f8 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -276,6 +276,9 @@ Type *alloc_type_struct_from_field_types(Type **field_types, isize field_count, } Type *alloc_type_tuple_from_field_types(Type **field_types, isize field_count, bool is_packed, bool must_be_tuple) { + if (field_count == 0) { + return nullptr; + } if (!must_be_tuple && field_count == 1) { return field_types[0]; } @@ -297,7 +300,9 @@ Type *alloc_type_proc_from_types(Type **param_types, unsigned param_count, Type Type *params = alloc_type_tuple_from_field_types(param_types, param_count, false, true); isize results_count = 0; if (results != nullptr) { - GB_ASSERT(results->kind == Type_Tuple); + if (results->kind != Type_Tuple) { + results = alloc_type_tuple_from_field_types(&results, 1, false, true); + } results_count = results->Tuple.variables.count; } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1f20c607d..43f4125ba 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -144,7 +144,7 @@ lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) { lbValue h = lb_gen_map_header(p, addr.addr, map_type); lbValue key = lb_gen_map_key(p, addr.map.key, map_type->Map.key); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = h; args[1] = key; @@ -209,7 +209,7 @@ void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue le lbValue line = lb_const_int(p->module, t_int, token.pos.line); lbValue column = lb_const_int(p->module, t_int, token.pos.column); - auto args = array_make(heap_allocator(), 5); + auto args = array_make(permanent_allocator(), 5); args[0] = file; args[1] = line; args[2] = column; @@ -233,7 +233,7 @@ void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValu high = lb_emit_conv(p, high, t_int); if (!lower_value_used) { - auto args = array_make(heap_allocator(), 5); + auto args = array_make(permanent_allocator(), 5); args[0] = file; args[1] = line; args[2] = column; @@ -245,7 +245,7 @@ void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValu // No need to convert unless used low = lb_emit_conv(p, low, t_int); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = file; args[1] = line; args[2] = column; @@ -357,7 +357,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { } - auto args = array_make(heap_allocator(), gb_max(arg_count, param_count)); + auto args = array_make(permanent_allocator(), gb_max(arg_count, param_count)); args[0] = ptr; args[1] = index; args[2] = value; @@ -594,7 +594,7 @@ lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) { lbValue h = lb_gen_map_header(p, addr.addr, map_type); lbValue key = lb_gen_map_key(p, addr.map.key, map_type->Map.key); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = h; args[1] = key; @@ -773,7 +773,6 @@ void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *varia } void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant, Type *variant_type) { - gbAllocator a = heap_allocator(); lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type)); lb_emit_store(p, underlying, variant); @@ -783,10 +782,9 @@ void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) { unsigned field_count = LLVMCountStructElementTypes(src); - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); + LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); LLVMGetStructElementTypes(src, fields); LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src)); - gb_free(heap_allocator(), fields); } LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) { @@ -821,8 +819,6 @@ bool lb_is_elem_const(Ast *elem, Type *elem_type) { } String lb_mangle_name(lbModule *m, Entity *e) { - gbAllocator a = heap_allocator(); - String name = e->token.string; AstPackage *pkg = e->pkg; @@ -848,7 +844,7 @@ String lb_mangle_name(lbModule *m, Entity *e) { max_len += 21; } - char *new_name = gb_alloc_array(a, char, max_len); + char *new_name = gb_alloc_array(permanent_allocator(), char, max_len); isize new_name_len = gb_snprintf( new_name, max_len, "%.*s.%.*s", LIT(pkgn), LIT(name) @@ -899,7 +895,7 @@ String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) { if (p != nullptr) { isize name_len = p->name.len + 1 + ts_name.len + 1 + 10 + 1; - char *name_text = gb_alloc_array(heap_allocator(), char, name_len); + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); u32 guid = ++p->module->nested_type_name_guid; name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%u", LIT(p->name), LIT(ts_name), guid); @@ -909,7 +905,7 @@ String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) { } else { // NOTE(bill): a nested type be required before its parameter procedure exists. Just give it a temp name for now isize name_len = 9 + 1 + ts_name.len + 1 + 10 + 1; - char *name_text = gb_alloc_array(heap_allocator(), char, name_len); + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); static u32 guid = 0; guid += 1; name_len = gb_snprintf(name_text, name_len, "_internal.%.*s-%u", LIT(ts_name), guid); @@ -1191,7 +1187,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { if (found) { LLVMTypeKind kind = LLVMGetTypeKind(*found); if (kind == LLVMStructTypeKind) { - char const *name = alloc_cstring(heap_allocator(), lb_get_entity_name(m, type->Named.type_name)); + char const *name = alloc_cstring(permanent_allocator(), lb_get_entity_name(m, type->Named.type_name)); LLVMTypeRef llvm_type = LLVMGetTypeByName(m->mod, name); if (llvm_type != nullptr) { return llvm_type; @@ -1208,7 +1204,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Type_Union: case Type_BitField: { - char const *name = alloc_cstring(heap_allocator(), lb_get_entity_name(m, type->Named.type_name)); + char const *name = alloc_cstring(permanent_allocator(), lb_get_entity_name(m, type->Named.type_name)); LLVMTypeRef llvm_type = LLVMGetTypeByName(m->mod, name); if (llvm_type != nullptr) { return llvm_type; @@ -1265,7 +1261,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { { if (type->Struct.is_raw_union) { unsigned field_count = 2; - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); + LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count); i64 alignment = type_align_of(type); unsigned size_of_union = cast(unsigned)type_size_of(type); fields[0] = lb_alignment_prefix_type_hack(m, alignment); @@ -1282,9 +1278,8 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { defer (m->internal_type_level -= 1); unsigned field_count = cast(unsigned)(type->Struct.fields.count + offset); - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); + LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); GB_ASSERT(fields != nullptr); - defer (gb_free(heap_allocator(), fields)); for_array(i, type->Struct.fields) { Entity *field = type->Struct.fields[i]; @@ -1344,8 +1339,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { return lb_type(m, type->Tuple.variables[0]->type); } else { unsigned field_count = cast(unsigned)(type->Tuple.variables.count); - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); - defer (gb_free(heap_allocator(), fields)); + LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); for_array(i, type->Tuple.variables) { Entity *field = type->Tuple.variables[i]; @@ -1444,8 +1438,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { } isize param_count = type->Proc.abi_compat_params.count + extra_param_count; - auto param_types = array_make(heap_allocator(), 0, param_count); - defer (array_free(¶m_types)); + auto param_types = array_make(temporary_allocator(), 0, param_count); if (type->Proc.return_by_pointer) { array_add(¶m_types, LLVMPointerType(lb_type(m, type->Proc.abi_compat_result_type), 0)); @@ -1492,8 +1485,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { { GB_ASSERT(type->BitField.fields.count == type->BitField.sizes.count); unsigned field_count = cast(unsigned)type->BitField.fields.count; - LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count); - defer (gb_free(heap_allocator(), fields)); + LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); for_array(i, type->BitField.sizes) { u32 size = type->BitField.sizes[i]; @@ -2135,7 +2127,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { } - lbProcedure *p = gb_alloc_item(heap_allocator(), lbProcedure); + lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure); p->module = m; entity->code_gen_module = m; @@ -2149,7 +2141,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { Type *pt = base_type(entity->type); GB_ASSERT(pt->kind == Type_Proc); - set_procedure_abi_types(heap_allocator(), entity->type); + set_procedure_abi_types(permanent_allocator(), entity->type); p->type = entity->type; p->type_expr = decl->type_expr; @@ -2172,7 +2164,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library); } - char *c_link_name = alloc_cstring(heap_allocator(), p->name); + char *c_link_name = alloc_cstring(permanent_allocator(), p->name); LLVMTypeRef func_ptr_type = lb_type(m, p->type); LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type); @@ -2209,19 +2201,19 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { LLVMSetVisibility(p->value, LLVMDefaultVisibility); if (build_context.metrics.os == TargetOs_js) { - char const *export_name = alloc_cstring(heap_allocator(), p->name); + char const *export_name = alloc_cstring(permanent_allocator(), p->name); LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", export_name); } } if (p->is_foreign) { if (build_context.metrics.os == TargetOs_js) { - char const *import_name = alloc_cstring(heap_allocator(), p->name); + char const *import_name = alloc_cstring(permanent_allocator(), p->name); char const *module_name = "env"; if (entity->Procedure.foreign_library != nullptr) { Entity *foreign_library = entity->Procedure.foreign_library; GB_ASSERT(foreign_library->kind == Entity_LibraryName); if (foreign_library->LibraryName.paths.count > 0) { - module_name = alloc_cstring(heap_allocator(), foreign_library->LibraryName.paths[0]); + module_name = alloc_cstring(permanent_allocator(), foreign_library->LibraryName.paths[0]); } } LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-name", import_name); @@ -2310,7 +2302,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type GB_ASSERT(found == nullptr); } - lbProcedure *p = gb_alloc_item(heap_allocator(), lbProcedure); + lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure); p->module = m; p->name = link_name; @@ -2324,7 +2316,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type p->is_export = false; p->is_entry_point = false; - gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); p->children.allocator = a; p->params.allocator = a; p->defer_stmts.allocator = a; @@ -2333,7 +2325,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type p->context_stack.allocator = a; - char *c_link_name = alloc_cstring(heap_allocator(), p->name); + char *c_link_name = alloc_cstring(permanent_allocator(), p->name); LLVMTypeRef func_ptr_type = lb_type(m, p->type); LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type); @@ -2833,7 +2825,7 @@ void lb_add_edge(lbBlock *from, lbBlock *to) { lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append) { - lbBlock *b = gb_alloc_item(heap_allocator(), lbBlock); + lbBlock *b = gb_alloc_item(permanent_allocator(), lbBlock); b->block = LLVMCreateBasicBlockInContext(p->module->ctx, name); b->appended = false; if (append) { @@ -2932,7 +2924,7 @@ lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, i32 p char const *name = ""; if (e != nullptr) { - // name = alloc_cstring(heap_allocator(), e->token.string); + // name = alloc_cstring(permanent_allocator(), e->token.string); } LLVMTypeRef llvm_type = lb_type(p->module, type); @@ -2980,13 +2972,13 @@ void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) { isize name_len = p->name.len + 1 + pd_name.len + 1 + 10 + 1; - char *name_text = gb_alloc_array(heap_allocator(), char, name_len); + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); i32 guid = cast(i32)p->children.count; name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%d", LIT(p->name), LIT(pd_name), guid); String name = make_string(cast(u8 *)name_text, name_len-1); - set_procedure_abi_types(heap_allocator(), e->type); + set_procedure_abi_types(permanent_allocator(), e->type); e->Procedure.link_name = name; @@ -3123,7 +3115,7 @@ void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) { return; } - set_procedure_abi_types(heap_allocator(), e->type); + set_procedure_abi_types(permanent_allocator(), e->type); e->Procedure.link_name = name; lbProcedure *nested_proc = lb_create_procedure(p->module, e); @@ -3179,7 +3171,7 @@ lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) { lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBlock *break_, lbBlock *continue_, lbBlock *fallthrough_) { - lbTargetList *tl = gb_alloc_item(heap_allocator(), lbTargetList); + lbTargetList *tl = gb_alloc_item(permanent_allocator(), lbTargetList); tl->prev = p->target_list; tl->break_ = break_; tl->continue_ = continue_; @@ -3400,7 +3392,7 @@ void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type, lbValue str_elem = lb_emit_ptr_offset(p, lb_string_elem(p, expr), offset); lbValue str_len = lb_emit_arith(p, Token_Sub, count, offset, t_int); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = lb_emit_string(p, str_elem, str_len); lbValue rune_and_len = lb_emit_runtime_call(p, "string_decode_rune", args); lbValue len = lb_emit_struct_ev(p, rune_and_len, 1); @@ -4275,14 +4267,14 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { String mangled_name = {}; { - gbString str = gb_string_make_length(heap_allocator(), p->name.text, p->name.len); + gbString str = gb_string_make_length(permanent_allocator(), p->name.text, p->name.len); str = gb_string_appendc(str, "-"); str = gb_string_append_fmt(str, ".%.*s-%llu", LIT(name), cast(long long)e->id); mangled_name.text = cast(u8 *)str; mangled_name.len = gb_string_length(str); } - char *c_name = alloc_cstring(heap_allocator(), mangled_name); + char *c_name = alloc_cstring(permanent_allocator(), mangled_name); LLVMValueRef global = LLVMAddGlobal(p->module->mod, lb_type(p->module, e->type), c_name); LLVMSetInitializer(global, LLVMConstNull(lb_type(p->module, e->type))); @@ -4329,8 +4321,8 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { } } } else { // Tuple(s) - auto lvals = array_make(heap_allocator(), 0, vd->names.count); - auto inits = array_make(heap_allocator(), 0, vd->names.count); + auto lvals = array_make(permanent_allocator(), 0, vd->names.count); + auto inits = array_make(permanent_allocator(), 0, vd->names.count); for_array(i, vd->names) { Ast *name = vd->names[i]; @@ -4367,7 +4359,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { case_ast_node(as, AssignStmt, node); if (as->op.kind == Token_Eq) { - auto lvals = array_make(heap_allocator(), 0, as->lhs.count); + auto lvals = array_make(permanent_allocator(), 0, as->lhs.count); for_array(i, as->lhs) { Ast *lhs = as->lhs[i]; @@ -4385,7 +4377,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { lbValue init = lb_build_expr(p, rhs); lb_addr_store(p, lvals[0], init); } else { - auto inits = array_make(heap_allocator(), 0, lvals.count); + auto inits = array_make(permanent_allocator(), 0, lvals.count); for_array(i, as->rhs) { lbValue init = lb_build_expr(p, as->rhs[i]); @@ -4399,7 +4391,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { } } } else { - auto inits = array_make(heap_allocator(), 0, lvals.count); + auto inits = array_make(permanent_allocator(), 0, lvals.count); for_array(i, as->rhs) { lbValue init = lb_build_expr(p, as->rhs[i]); @@ -4491,7 +4483,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { } } else { - auto results = array_make(heap_allocator(), 0, return_count); + auto results = array_make(permanent_allocator(), 0, return_count); if (res_count != 0) { for (isize res_index = 0; res_index < res_count; res_index++) { @@ -4794,9 +4786,8 @@ lbValue lb_emit_min(lbProcedure *p, Type *t, lbValue x, lbValue y) { y = lb_emit_conv(p, y, t); if (is_type_float(t)) { - gbAllocator a = heap_allocator(); i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = x; args[1] = y; switch (sz) { @@ -4812,9 +4803,8 @@ lbValue lb_emit_max(lbProcedure *p, Type *t, lbValue x, lbValue y) { y = lb_emit_conv(p, y, t); if (is_type_float(t)) { - gbAllocator a = heap_allocator(); i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = x; args[1] = y; switch (sz) { @@ -4850,7 +4840,7 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) { isize max_len = 7+8+1; - char *name = gb_alloc_array(heap_allocator(), char, max_len); + char *name = gb_alloc_array(permanent_allocator(), char, max_len); isize len = gb_snprintf(name, max_len, "csbs$%x", m->global_array_index); len -= 1; m->global_array_index++; @@ -4892,7 +4882,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) char *name = nullptr; { isize max_len = 7+8+1; - name = gb_alloc_array(heap_allocator(), char, max_len); + name = gb_alloc_array(permanent_allocator(), char, max_len); isize len = gb_snprintf(name, max_len, "csbs$%x", m->global_array_index); len -= 1; m->global_array_index++; @@ -5103,7 +5093,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } } else { isize max_len = 7+8+1; - char *str = gb_alloc_array(heap_allocator(), char, max_len); + char *str = gb_alloc_array(permanent_allocator(), char, max_len); isize len = gb_snprintf(str, max_len, "csba$%x", m->global_array_index); m->global_array_index++; @@ -5151,7 +5141,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc lbValue single_elem = lb_const_value(m, elem, value, allow_local); - LLVMValueRef *elems = gb_alloc_array(heap_allocator(), LLVMValueRef, count); + LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count); for (i64 i = 0; i < count; i++) { elems[i] = single_elem.value; } @@ -5204,7 +5194,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc isize byte_len = gb_size_of(u64)*len; u8 *old_bytes = cast(u8 *)words; // TODO(bill): Use a different allocator here for a temporary allocation - u8 *new_bytes = cast(u8 *)gb_alloc_align(heap_allocator(), byte_len, gb_align_of(u64)); + u8 *new_bytes = cast(u8 *)gb_alloc_align(permanent_allocator(), byte_len, gb_align_of(u64)); for (i64 i = 0; i < sz; i++) { new_bytes[i] = old_bytes[sz-1-i]; } @@ -5291,8 +5281,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc if (cl->elems[0]->kind == Ast_FieldValue) { // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, type->Array.count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count); isize value_index = 0; for (i64 i = 0; i < type->Array.count; i++) { @@ -5349,8 +5338,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } else { GB_ASSERT_MSG(elem_count == type->Array.count, "%td != %td", elem_count, type->Array.count); - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, type->Array.count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count); for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; @@ -5374,8 +5362,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc if (cl->elems[0]->kind == Ast_FieldValue) { // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, type->EnumeratedArray.count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count); isize value_index = 0; @@ -5436,8 +5423,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } else { GB_ASSERT_MSG(elem_count == type->EnumeratedArray.count, "%td != %td", elem_count, type->EnumeratedArray.count); - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, type->EnumeratedArray.count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count); for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; @@ -5462,8 +5448,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc GB_ASSERT(elem_type_can_be_constant(elem_type)); isize total_elem_count = type->SimdVector.count; - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, total_elem_count); - defer (gb_free(heap_allocator(), values)); + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, total_elem_count); for (isize i = 0; i < elem_count; i++) { TypeAndValue tav = cl->elems[i]->tav; @@ -5489,11 +5474,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } isize value_count = type->Struct.fields.count + offset; - LLVMValueRef *values = gb_alloc_array(heap_allocator(), LLVMValueRef, value_count); - bool *visited = gb_alloc_array(heap_allocator(), bool, value_count); - defer (gb_free(heap_allocator(), values)); - defer (gb_free(heap_allocator(), visited)); - + LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count); + bool *visited = gb_alloc_array(temporary_allocator(), bool, value_count); if (cl->elems.count > 0) { @@ -5822,7 +5804,7 @@ lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Ty Type *ft = base_complex_elem_type(type); if (op == Token_Quo) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = lhs; args[1] = rhs; @@ -5896,7 +5878,7 @@ lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Ty return lb_addr_load(p, res); } else if (op == Token_Mul) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = lhs; args[1] = rhs; @@ -5906,7 +5888,7 @@ lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Ty default: GB_PANIC("Unknown float type"); break; } } else if (op == Token_Quo) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = lhs; args[1] = rhs; @@ -6132,7 +6114,7 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) { lbValue h = lb_gen_map_header(p, addr, rt); lbValue key = lb_gen_map_key(p, left, rt->Map.key); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = h; args[1] = key; @@ -6378,7 +6360,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { if (are_types_identical(src, t_cstring) && are_types_identical(dst, t_string)) { lbValue c = lb_emit_conv(p, value, t_cstring); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = c; lbValue s = lb_emit_runtime_call(p, "cstring_to_string", args); return lb_emit_conv(p, s, dst); @@ -6395,7 +6377,6 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { // float -> float if (is_type_float(src) && is_type_float(dst)) { - gbAllocator a = heap_allocator(); i64 sz = type_size_of(src); i64 dz = type_size_of(dst); @@ -6837,8 +6818,7 @@ void lb_emit_init_context(lbProcedure *p, lbAddr addr) { GB_ASSERT(addr.ctx.sel.index.count == 0); lbModule *m = p->module; - gbAllocator a = heap_allocator(); - auto args = array_make(a, 1); + auto args = array_make(permanent_allocator(), 1); args[0] = addr.addr; lb_emit_runtime_call(p, "__init_context", args); } @@ -6907,7 +6887,6 @@ lbValue lb_copy_value_to_ptr(lbProcedure *p, lbValue val, Type *new_type, i64 al } lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) { - gbAllocator a = heap_allocator(); GB_ASSERT(is_type_pointer(s.type)); Type *t = base_type(type_deref(s.type)); Type *result_type = nullptr; @@ -7015,7 +6994,6 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) { return lb_emit_load(p, ptr); } - gbAllocator a = heap_allocator(); Type *t = base_type(s.type); Type *result_type = nullptr; @@ -7121,7 +7099,6 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) { lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) { GB_ASSERT(sel.index.count > 0); Type *type = type_deref(e.type); - gbAllocator a = heap_allocator(); for_array(i, sel.index) { i32 index = cast(i32)sel.index[i]; @@ -7292,14 +7269,14 @@ Array lb_value_to_array(lbProcedure *p, lbValue value) { GB_ASSERT(t->kind == Type_Tuple); auto *rt = &t->Tuple; if (rt->variables.count > 0) { - array = array_make(heap_allocator(), rt->variables.count); + array = array_make(permanent_allocator(), rt->variables.count); for_array(i, rt->variables) { lbValue elem = lb_emit_struct_ev(p, value, cast(i32)i); array[i] = elem; } } } else { - array = array_make(heap_allocator(), 1); + array = array_make(permanent_allocator(), 1); array[0] = value; } return array; @@ -7316,7 +7293,7 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, arg_count += 1; } - LLVMValueRef *args = gb_alloc_array(heap_allocator(), LLVMValueRef, arg_count); + LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count); isize arg_index = 0; if (return_ptr.value != nullptr) { args[arg_index++] = return_ptr.value; @@ -7399,7 +7376,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array const &args, LLVMBuildUnreachable(p->builder); }); - set_procedure_abi_types(heap_allocator(), pt); + set_procedure_abi_types(permanent_allocator(), pt); bool is_c_vararg = pt->Proc.c_vararg; isize param_count = pt->Proc.param_count; @@ -7412,7 +7389,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array const &args, lbValue result = {}; - auto processed_args = array_make(heap_allocator(), 0, args.count); + auto processed_args = array_make(permanent_allocator(), 0, args.count); if (USE_LLVM_ABI) { lbFunctionType **ft_found = nullptr; @@ -7635,7 +7612,7 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array const &args, case DeferredProcedure_in_out: { auto out_args = lb_value_to_array(p, result); - array_init(&result_as_args, heap_allocator(), in_args.count + out_args.count); + array_init(&result_as_args, permanent_allocator(), in_args.count + out_args.count); array_copy(&result_as_args, in_args, 0); array_copy(&result_as_args, out_args, in_args.count); } @@ -7744,7 +7721,7 @@ lbValue lb_string_len(lbProcedure *p, lbValue string) { lbValue lb_cstring_len(lbProcedure *p, lbValue value) { GB_ASSERT(is_type_cstring(value.type)); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = lb_emit_conv(p, value, t_cstring); return lb_emit_runtime_call(p, "cstring_len", args); } @@ -7782,7 +7759,6 @@ lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da) { } lbValue lb_map_entries(lbProcedure *p, lbValue value) { - gbAllocator a = heap_allocator(); Type *t = base_type(value.type); GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t)); init_map_internal_types(t); @@ -7793,7 +7769,6 @@ lbValue lb_map_entries(lbProcedure *p, lbValue value) { } lbValue lb_map_entries_ptr(lbProcedure *p, lbValue value) { - gbAllocator a = heap_allocator(); Type *t = base_type(type_deref(value.type)); GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t)); init_map_internal_types(t); @@ -7917,7 +7892,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } GB_ASSERT(is_type_typeid(tav.type)); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = lb_build_expr(p, arg); return lb_emit_runtime_call(p, "__type_info_of", args); } @@ -7994,7 +7969,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } unsigned mask_len = cast(unsigned)index_count; - LLVMValueRef *mask_elems = gb_alloc_array(heap_allocator(), LLVMValueRef, index_count); + LLVMValueRef *mask_elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, index_count); for (isize i = 1; i < ce->args.count; i++) { TypeAndValue tv = type_and_value_of_expr(ce->args[i]); GB_ASSERT(is_type_integer(tv.type)); @@ -8224,7 +8199,6 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } case BuiltinProc_abs: { - gbAllocator a = heap_allocator(); lbValue x = lb_build_expr(p, ce->args[0]); Type *t = x.type; if (is_type_unsigned(t)) { @@ -8232,7 +8206,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } if (is_type_quaternion(t)) { i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = x; switch (sz) { case 128: return lb_emit_runtime_call(p, "abs_quaternion128", args); @@ -8241,7 +8215,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, GB_PANIC("Unknown complex type"); } else if (is_type_complex(t)) { i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = x; switch (sz) { case 64: return lb_emit_runtime_call(p, "abs_complex64", args); @@ -8250,7 +8224,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, GB_PANIC("Unknown complex type"); } else if (is_type_float(t)) { i64 sz = 8*type_size_of(t); - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = x; switch (sz) { case 32: return lb_emit_runtime_call(p, "abs_f32", args); @@ -8506,7 +8480,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, GB_ASSERT(tv.type->kind == Type_Tuple); Type *fix_typed = alloc_type_tuple(); - array_init(&fix_typed->Tuple.variables, heap_allocator(), 2); + array_init(&fix_typed->Tuple.variables, permanent_allocator(), 2); fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0]; fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1); @@ -8621,10 +8595,10 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { Type *proc_type_ = base_type(value.type); GB_ASSERT(proc_type_->kind == Type_Proc); TypeProc *pt = &proc_type_->Proc; - set_procedure_abi_types(heap_allocator(), proc_type_); + set_procedure_abi_types(permanent_allocator(), proc_type_); if (is_call_expr_field_value(ce)) { - auto args = array_make(heap_allocator(), pt->param_count); + auto args = array_make(permanent_allocator(), pt->param_count); for_array(arg_index, ce->args) { Ast *arg = ce->args[arg_index]; @@ -8693,7 +8667,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { param_count = pt->params->Tuple.variables.count; } - auto args = array_make(heap_allocator(), cast(isize)gb_max(param_count, arg_count)); + auto args = array_make(permanent_allocator(), cast(isize)gb_max(param_count, arg_count)); isize variadic_index = pt->variadic_index; bool variadic = pt->variadic && variadic_index >= 0; bool vari_expand = ce->ellipsis.pos.line != 0; @@ -8801,7 +8775,6 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { if (variadic && !vari_expand && !is_c_vararg) { // variadic call argument generation - gbAllocator allocator = heap_allocator(); Type *slice_type = param_tuple->variables[variadic_index]->type; Type *elem_type = base_type(slice_type)->Slice.elem; lbAddr slice = lb_add_local_generated(p, slice_type, true); @@ -9077,7 +9050,7 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { lbValue invalid_typeid = lb_const_value(p->module, t_typeid, exact_value_i64(0)); return lb_emit_comp(p, op_kind, x, invalid_typeid); } else if (is_type_bit_field(t)) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); lbValue lhs = lb_address_from_load_or_generate_local(p, x); args[0] = lb_emit_conv(p, lhs, t_rawptr); args[1] = lb_const_int(p->module, t_int, type_size_of(t)); @@ -9106,7 +9079,7 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) { } } } else if (is_type_struct(t) && type_has_nil(t)) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); lbValue lhs = lb_address_from_load_or_generate_local(p, x); args[0] = lb_emit_conv(p, lhs, t_rawptr); args[1] = lb_const_int(p->module, t_int, type_size_of(t)); @@ -9141,8 +9114,6 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } else if (lb_is_const(right) || lb_is_const_nil(right)) { right = lb_emit_conv(p, right, left.type); } else { - gbAllocator a = heap_allocator(); - Type *lt = left.type; Type *rt = right.type; @@ -9222,7 +9193,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } else { if (is_type_simple_compare(tl) && (op_kind == Token_CmpEq || op_kind == Token_NotEq)) { // TODO(bill): Test to see if this is actually faster!!!! - auto args = array_make(heap_allocator(), 3); + auto args = array_make(permanent_allocator(), 3); args[0] = lb_emit_conv(p, lhs, t_rawptr); args[1] = lb_emit_conv(p, rhs, t_rawptr); args[2] = lb_const_int(p->module, t_int, type_size_of(tl)); @@ -9265,7 +9236,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } GB_ASSERT(runtime_procedure != nullptr); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; return lb_emit_runtime_call(p, runtime_procedure, args); @@ -9290,7 +9261,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } GB_ASSERT(runtime_procedure != nullptr); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; return lb_emit_runtime_call(p, runtime_procedure, args); @@ -9315,7 +9286,7 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } GB_ASSERT(runtime_procedure != nullptr); - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; return lb_emit_runtime_call(p, runtime_procedure, args); @@ -9464,14 +9435,14 @@ lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, A // NOTE(bill): Generate a new name // parent$count isize name_len = prefix_name.len + 1 + 8 + 1; - char *name_text = gb_alloc_array(heap_allocator(), char, name_len); + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); i32 name_id = cast(i32)m->anonymous_proc_lits.entries.count; name_len = gb_snprintf(name_text, name_len, "%.*s$anon-%d", LIT(prefix_name), name_id); String name = make_string((u8 *)name_text, name_len-1); Type *type = type_of_expr(expr); - set_procedure_abi_types(heap_allocator(), type); + set_procedure_abi_types(permanent_allocator(), type); Token token = {}; @@ -9567,7 +9538,7 @@ lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos p Type *dst_type = tuple->Tuple.variables[0]->type; lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = ok; args[1] = lb_const_string(m, pos.file); @@ -9628,7 +9599,7 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos // NOTE(bill): Panic on invalid conversion lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = ok; args[1] = lb_const_string(m, pos.file); @@ -9912,7 +9883,6 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { return addr.addr; } else if (ue_expr->kind == Ast_TypeAssertion) { - gbAllocator a = heap_allocator(); GB_ASSERT(is_type_pointer(tv.type)); ast_node(ta, TypeAssertion, ue_expr); @@ -9934,7 +9904,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbValue dst_tag = lb_const_union_tag(p->module, src_type, dst_type); lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = ok; args[1] = lb_find_or_add_entity_string(p->module, pos.file); @@ -9959,7 +9929,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id); - auto args = array_make(heap_allocator(), 6); + auto args = array_make(permanent_allocator(), 6); args[0] = ok; args[1] = lb_find_or_add_entity_string(p->module, pos.file); @@ -10110,7 +10080,6 @@ lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *expr) { lbValue lb_gen_map_header(lbProcedure *p, lbValue map_val_ptr, Type *map_type) { GB_ASSERT_MSG(is_type_pointer(map_val_ptr.type), "%s", type_to_string(map_val_ptr.type)); - gbAllocator a = heap_allocator(); lbAddr h = lb_add_local_generated(p, t_map_header, false); // all the values will be initialzed later map_type = base_type(map_type); GB_ASSERT(map_type->kind == Type_Map); @@ -10154,7 +10123,7 @@ lbValue lb_gen_map_key(lbProcedure *p, lbValue key, Type *key_type) { u64 hs = fnv64a(v.text, v.len); hashed_str = lb_const_int(p->module, t_u64, hs); } else { - auto args = array_make(heap_allocator(), 1); + auto args = array_make(permanent_allocator(), 1); args[0] = str; hashed_str = lb_emit_runtime_call(p, "default_hash_string", args); } @@ -10167,7 +10136,7 @@ lbValue lb_gen_map_key(lbProcedure *p, lbValue key, Type *key_type) { i64 sz = type_size_of(t); GB_ASSERT(sz <= 8); if (sz != 0) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = lb_address_from_load_or_generate_local(p, key); args[1] = lb_const_int(p->module, t_int, sz); lbValue hash = lb_emit_runtime_call(p, "default_hash_ptr", args); @@ -10197,7 +10166,7 @@ void lb_insert_dynamic_map_key_and_value(lbProcedure *p, lbAddr addr, Type *map_ lbAddr value_addr = lb_add_local_generated(p, v.type, false); lb_addr_store(p, value_addr, v); - auto args = array_make(heap_allocator(), 4); + auto args = array_make(permanent_allocator(), 4); args[0] = h; args[1] = key; args[2] = lb_emit_conv(p, value_addr.addr, t_rawptr); @@ -10356,7 +10325,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { case_end; case_ast_node(ta, TypeAssertion, expr); - gbAllocator a = heap_allocator(); TokenPos pos = ast_token(expr).pos; lbValue e = lb_build_expr(p, ta->expr); Type *t = type_deref(e.type); @@ -10393,7 +10361,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { case_ast_node(ie, IndexExpr, expr); Type *t = base_type(type_of_expr(ie->expr)); - gbAllocator a = heap_allocator(); bool deref = is_type_pointer(t); t = base_type(type_deref(t)); @@ -10593,7 +10560,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { case_end; case_ast_node(se, SliceExpr, expr); - gbAllocator a = heap_allocator(); lbValue low = lb_const_int(p->module, t_int, 0); lbValue high = {}; @@ -10892,9 +10858,8 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count == 0) { break; } - gbAllocator a = heap_allocator(); { - auto args = array_make(a, 3); + auto args = array_make(permanent_allocator(), 3); args[0] = lb_gen_map_header(p, v.addr, type); args[1] = lb_const_int(p->module, t_int, 2*cl->elems.count); args[2] = lb_emit_source_code_location(p, proc_name, pos); @@ -10915,8 +10880,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks for_array(i, cl->elems) { @@ -11015,8 +10979,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks for_array(i, cl->elems) { @@ -11124,8 +11087,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { lbValue data = lb_slice_elem(p, slice); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); for_array(i, cl->elems) { Ast *elem = cl->elems[i]; @@ -11218,14 +11180,13 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { break; } Type *et = bt->DynamicArray.elem; - gbAllocator a = heap_allocator(); lbValue size = lb_const_int(p->module, t_int, type_size_of(et)); lbValue align = lb_const_int(p->module, t_int, type_align_of(et)); i64 item_count = gb_max(cl->max_count, cl->elems.count); { - auto args = array_make(a, 5); + auto args = array_make(permanent_allocator(), 5); args[0] = lb_emit_conv(p, lb_addr_get_ptr(p, v), t_rawptr); args[1] = size; args[2] = align; @@ -11279,7 +11240,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { } { - auto args = array_make(a, 6); + auto args = array_make(permanent_allocator(), 6); args[0] = lb_emit_conv(p, v.addr, t_rawptr); args[1] = size; args[2] = align; @@ -11491,7 +11452,7 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) { type = default_type(type); isize max_len = 7+8+1; - u8 *str = cast(u8 *)gb_alloc_array(heap_allocator(), u8, max_len); + u8 *str = cast(u8 *)gb_alloc_array(permanent_allocator(), u8, max_len); isize len = gb_snprintf(cast(char *)str, max_len, "ggv$%x", m->global_generated_index); m->global_generated_index++; String name = make_string(str, len-1); @@ -11571,12 +11532,11 @@ lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool } lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id) { - gbAllocator a = heap_allocator(); Token token = {Token_Ident}; isize name_len = prefix.len + 1 + 20; auto suffix_id = cast(unsigned long long)id; - char *text = gb_alloc_array(a, char, name_len+1); + char *text = gb_alloc_array(permanent_allocator(), char, name_len+1); gb_snprintf(text, name_len, "%.*s-%llu", LIT(prefix), suffix_id); text[name_len] = 0; @@ -11598,7 +11558,6 @@ lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info data lbModule *m = p->module; LLVMContextRef ctx = m->ctx; - gbAllocator a = heap_allocator(); CheckerInfo *info = m->info; { @@ -11976,10 +11935,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da str_lit("$enum_values"), cast(i64)entry_index); - LLVMValueRef *name_values = gb_alloc_array(heap_allocator(), LLVMValueRef, fields.count); - LLVMValueRef *value_values = gb_alloc_array(heap_allocator(), LLVMValueRef, fields.count); - defer (gb_free(heap_allocator(), name_values)); - defer (gb_free(heap_allocator(), value_values)); + LLVMValueRef *name_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count); + LLVMValueRef *value_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count); GB_ASSERT(is_type_integer(t->Enum.base_type)); @@ -12328,10 +12285,6 @@ void lb_generate_code(lbGenerator *gen) { LLVMModuleRef mod = gen->module.mod; CheckerInfo *info = gen->info; - Arena temp_arena = {}; - arena_init(&temp_arena, heap_allocator()); - gbAllocator temp_allocator = arena_allocator(&temp_arena); - auto *min_dep_set = &info->minimum_dependency_set; @@ -12344,8 +12297,8 @@ void lb_generate_code(lbGenerator *gen) { LLVMInitializeNativeTarget(); - char const *target_triple = alloc_cstring(heap_allocator(), build_context.metrics.target_triplet); - char const *target_data_layout = alloc_cstring(heap_allocator(), build_context.metrics.target_data_layout); + char const *target_triple = alloc_cstring(permanent_allocator(), build_context.metrics.target_triplet); + char const *target_data_layout = alloc_cstring(permanent_allocator(), build_context.metrics.target_data_layout); LLVMSetTarget(mod, target_triple); LLVMTargetRef target = {}; @@ -12367,7 +12320,7 @@ void lb_generate_code(lbGenerator *gen) { if (build_context.microarch == "native") { llvm_cpu = host_cpu_name; } else { - llvm_cpu = alloc_cstring(heap_allocator(), build_context.microarch); + llvm_cpu = alloc_cstring(permanent_allocator(), build_context.microarch); } if (gb_strcmp(llvm_cpu, host_cpu_name) == 0) { llvm_features = LLVMGetHostCPUFeatures(); @@ -12538,7 +12491,7 @@ void lb_generate_code(lbGenerator *gen) { lbValue init; DeclInfo *decl; }; - auto global_variables = array_make(heap_allocator(), 0, global_variable_max_count); + auto global_variables = array_make(permanent_allocator(), 0, global_variable_max_count); for_array(i, info->variable_init_order) { DeclInfo *d = info->variable_init_order[i]; @@ -12565,7 +12518,7 @@ void lb_generate_code(lbGenerator *gen) { lbValue g = {}; - g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(heap_allocator(), name)); + g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); g.type = alloc_type_pointer(e->type); if (e->Variable.thread_local_model != "") { LLVMSetThreadLocal(g.value, true); @@ -12619,9 +12572,6 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Global Procedures and Types"); for_array(i, info->entities) { - // arena_free_all(&temp_arena); - // gbAllocator a = temp_allocator; - Entity *e = info->entities[i]; String name = e->token.string; DeclInfo *decl = e->decl_info; @@ -12906,12 +12856,12 @@ void lb_generate_code(lbGenerator *gen) { if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_386) { name = str_lit("mainCRTStartup"); } else { - array_init(¶ms->Tuple.variables, heap_allocator(), 2); + array_init(¶ms->Tuple.variables, permanent_allocator(), 2); params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true); params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), alloc_type_pointer(t_cstring), false, true); } - array_init(&results->Tuple.variables, heap_allocator(), 1); + array_init(&results->Tuple.variables, permanent_allocator(), 1); results->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("_"), t_i32, false, true); Type *proc_type = alloc_type_proc(nullptr, @@ -12944,8 +12894,7 @@ void lb_generate_code(lbGenerator *gen) { } - String filepath_ll = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".ll")); - defer (gb_free(heap_allocator(), filepath_ll.text)); + String filepath_ll = concatenate_strings(temporary_allocator(), gen->output_base, STR_LIT(".ll")); TIME_SECTION("LLVM Procedure Generation"); for_array(i, m->procedures_to_generate) { @@ -13032,20 +12981,20 @@ void lb_generate_code(lbGenerator *gen) { LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile; if (build_context.build_mode == BuildMode_Assembly) { - filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".S")); + filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".S")); code_gen_file_type = LLVMAssemblyFile; } else { switch (build_context.metrics.os) { case TargetOs_windows: - filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".obj")); + filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".obj")); break; case TargetOs_darwin: case TargetOs_linux: case TargetOs_essence: - filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".o")); + filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".o")); break; case TargetOs_js: - filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".wasm-obj")); + filepath_obj = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".wasm-obj")); break; } } diff --git a/src/main.cpp b/src/main.cpp index 3717a4147..d0d2e2bbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1643,12 +1643,15 @@ int main(int arg_count, char const **arg_ptr) { timings_init(timings, str_lit("Total Time"), 128); defer (timings_destroy(timings)); + arena_init(&permanent_arena, heap_allocator()); + arena_init(&temporary_arena, heap_allocator()); + arena_init(&global_ast_arena, heap_allocator()); + init_string_buffer_memory(); init_string_interner(); init_global_error_collector(); init_keyword_hash_table(); global_big_int_init(); - arena_init(&global_ast_arena, heap_allocator()); array_init(&library_collections, heap_allocator()); // NOTE(bill): 'core' cannot be (re)defined by the user @@ -1795,6 +1798,8 @@ int main(int arg_count, char const **arg_ptr) { return 1; } + arena_free_all(&temporary_arena); + if (build_context.generate_docs) { // generate_documentation(&parser); return 0; @@ -1812,6 +1817,7 @@ int main(int arg_count, char const **arg_ptr) { check_parsed_files(&checker); } + arena_free_all(&temporary_arena); if (build_context.no_output_files) { if (build_context.query_data_set_settings.ok) { @@ -1842,6 +1848,8 @@ int main(int arg_count, char const **arg_ptr) { } lb_generate_code(&gen); + arena_free_all(&temporary_arena); + switch (build_context.build_mode) { case BuildMode_Executable: case BuildMode_DynamicLibrary: @@ -1919,12 +1927,18 @@ int main(int arg_count, char const **arg_ptr) { timings_start_section(timings, str_lit("llvm ir gen")); ir_gen_tree(&ir_gen); + arena_free_all(&temporary_arena); + timings_start_section(timings, str_lit("llvm ir opt tree")); ir_opt_tree(&ir_gen); + arena_free_all(&temporary_arena); + timings_start_section(timings, str_lit("llvm ir print")); print_llvm_ir(&ir_gen); + arena_free_all(&temporary_arena); + String output_name = ir_gen.output_name; String output_base = ir_gen.output_base; diff --git a/src/parser.cpp b/src/parser.cpp index 794ff231d..5e04aea17 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -108,6 +108,30 @@ Token ast_token(Ast *node) { return empty_token; } + +gb_global gbAtomic64 total_allocated_node_memory = {0}; +gb_global gbAtomic64 total_subtype_node_memory_test = {0}; + +isize ast_node_size(AstKind kind) { + return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *)); + +} +// NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++ +Ast *alloc_ast_node(AstFile *f, AstKind kind) { + gbAllocator a = ast_allocator(f); + + isize size = ast_node_size(kind); + + gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast))); + gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind])); + + // Ast *node = gb_alloc_item(a, Ast); + Ast *node = cast(Ast *)gb_alloc(a, size); + node->kind = kind; + node->file = f; + return node; +} + Ast *clone_ast(Ast *node); Array clone_ast_array(Array array) { Array result = {}; @@ -125,7 +149,7 @@ Ast *clone_ast(Ast *node) { return nullptr; } Ast *n = alloc_ast_node(node->file, node->kind); - gb_memmove(n, node, gb_size_of(Ast)); + gb_memmove(n, node, ast_node_size(node->kind)); switch (n->kind) { default: GB_PANIC("Unhandled Ast %.*s", LIT(ast_strings[n->kind])); break; @@ -463,23 +487,6 @@ bool ast_node_expect(Ast *node, AstKind kind) { return true; } - -gb_global gbAtomic64 total_allocated_node_memory = {0}; -gb_global gbAtomic64 total_subtype_node_memory_test = {0}; - -// NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++ -Ast *alloc_ast_node(AstFile *f, AstKind kind) { - gbAllocator a = ast_allocator(f); - - gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast))); - gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind])); - - Ast *node = gb_alloc_item(a, Ast); - node->kind = kind; - node->file = f; - return node; -} - Ast *ast_bad_expr(AstFile *f, Token begin, Token end) { Ast *result = alloc_ast_node(f, Ast_BadExpr); result->BadExpr.begin = begin; diff --git a/src/parser.hpp b/src/parser.hpp index 8e210876f..0804652a3 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -655,6 +655,7 @@ struct Ast { Scope * scope; TypeAndValue tav; + // IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant union { #define AST_KIND(_kind_name_, name, ...) GB_JOIN2(Ast, _kind_name_) _kind_name_; AST_KINDS diff --git a/src/types.cpp b/src/types.cpp index 1a55c9b05..17dcedf45 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -771,7 +771,8 @@ void set_base_type(Type *t, Type *base) { Type *alloc_type(TypeKind kind) { - gbAllocator a = heap_allocator(); + // gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); Type *t = gb_alloc_item(a, Type); zero_item(t); t->kind = kind; @@ -2340,7 +2341,7 @@ Selection lookup_field_from_index(Type *type, i64 index) { GB_ASSERT(is_type_struct(type) || is_type_union(type) || is_type_tuple(type)); type = base_type(type); - gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); isize max_count = 0; switch (type->kind) { case Type_Struct: max_count = type->Struct.fields.count; break; @@ -2397,7 +2398,6 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty return empty_selection; } - gbAllocator a = heap_allocator(); Type *type = type_deref(type_); bool is_ptr = type != type_; sel.indirect = sel.indirect || is_ptr; @@ -2986,7 +2986,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) { } Array type_set_offsets_of(Array const &fields, bool is_packed, bool is_raw_union) { - gbAllocator a = heap_allocator(); + gbAllocator a = permanent_allocator(); auto offsets = array_make(a, fields.count); i64 curr_offset = 0; if (is_raw_union) { -- cgit v1.2.3 From 17ec3e72a68b805fc202174722778545c956f433 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 Nov 2020 18:45:40 +0000 Subject: Add SCOPED_TEMPORARY_BLOCK for temporary allocations within a block --- src/check_decl.cpp | 9 ++++----- src/check_expr.cpp | 53 ++++++++++++++++++++++++++-------------------------- src/check_stmt.cpp | 30 ++++++++++++++--------------- src/check_type.cpp | 45 +++++++++++++++++++++----------------------- src/checker.cpp | 35 ++++++++++++++++------------------ src/checker.hpp | 2 -- src/common.cpp | 35 +++++++++++++++++++++++++++++++++- src/gb/gb.h | 2 +- src/ir.cpp | 31 ++++++++++++++---------------- src/ir_print.cpp | 6 +++--- src/llvm_backend.cpp | 28 +++++++++++++++++++++++---- src/main.cpp | 1 + 12 files changed, 159 insertions(+), 118 deletions(-) (limited to 'src/main.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 1aafa6e1c..bfe703853 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -121,8 +121,8 @@ void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Ar // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation - auto operands = array_make(ctx->allocator, 0, 2*lhs_count); - defer (array_free(&operands)); + SCOPED_TEMPORARY_BLOCK(); + auto operands = array_make(temporary_allocator(), 0, 2*lhs_count); check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false); isize rhs_count = operands.count; @@ -317,7 +317,6 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) break; default: error(e->token, "Only struct types can have custom atom operations"); - gb_free(heap_allocator(), ac.atom_op_table); break; } } @@ -638,7 +637,7 @@ String handle_link_name(CheckerContext *ctx, Token token, String link_name, Stri error(token, "'link_name' and 'link_prefix' cannot be used together"); } else { isize len = link_prefix.len + token.string.len; - u8 *name = gb_alloc_array(ctx->allocator, u8, len+1); + u8 *name = gb_alloc_array(permanent_allocator(), u8, len+1); gb_memmove(name, &link_prefix[0], link_prefix.len); gb_memmove(name+link_prefix.len, &token.string[0], token.string.len); name[len] = 0; @@ -975,7 +974,7 @@ void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d) ast_node(pg, ProcGroup, d->init_expr); - pge->entities = array_make(ctx->allocator, 0, pg->args.count); + pge->entities = array_make(permanent_allocator(), 0, pg->args.count); // NOTE(bill): This must be set here to prevent cycles in checking if someone // places the entity within itself diff --git a/src/check_expr.cpp b/src/check_expr.cpp index cf4304053..755ceb634 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -267,7 +267,7 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *c, Entity *base_enti CheckerContext nctx = *c; - Scope *scope = create_scope(base_entity->scope, a); + Scope *scope = create_scope(base_entity->scope); scope->flags |= ScopeFlag_Proc; nctx.scope = scope; nctx.allow_polymorphic_types = true; @@ -366,7 +366,7 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *c, Entity *base_enti u64 tags = base_entity->Procedure.tags; Ast *ident = clone_ast(base_entity->identifier); Token token = ident->Ident.token; - DeclInfo *d = make_decl_info(nctx.allocator, scope, old_decl->parent); + DeclInfo *d = make_decl_info(scope, old_decl->parent); d->gen_proc_type = final_proc_type; d->type_expr = pl->type; d->proc_lit = proc_lit; @@ -1832,12 +1832,9 @@ void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { } + SCOPED_TEMPORARY_BLOCK(); gbString err_str = nullptr; - defer (if (err_str != nullptr) { - gb_string_free(err_str); - }); - if (check_is_assignable_to(c, x, y->type) || check_is_assignable_to(c, y, x->type)) { Type *err_type = x->type; @@ -1867,8 +1864,8 @@ void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { } gbString type_string = type_to_string(err_type); defer (gb_string_free(type_string)); - err_str = gb_string_make(c->allocator, - gb_bprintf("operator '%.*s' not defined for type '%s'", LIT(token_strings[op]), type_string)); + err_str = gb_string_make(temporary_allocator(), + gb_bprintf("operator '%.*s' not defined for type '%s'", LIT(token_strings[op]), type_string)); } } else { gbString xt, yt; @@ -1882,8 +1879,7 @@ void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { } else { yt = type_to_string(y->type); } - err_str = gb_string_make(c->allocator, - gb_bprintf("mismatched types '%s' and '%s'", xt, yt)); + err_str = gb_string_make(temporary_allocator(), gb_bprintf("mismatched types '%s' and '%s'", xt, yt)); gb_string_free(yt); gb_string_free(xt); } @@ -2978,9 +2974,10 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { case Type_Union: if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) { + SCOPED_TEMPORARY_BLOCK(); + isize count = t->Union.variants.count; - ValidIndexAndScore *valids = gb_alloc_array(c->allocator, ValidIndexAndScore, count); - defer (gb_free(c->allocator, valids)); + ValidIndexAndScore *valids = gb_alloc_array(temporary_allocator(), ValidIndexAndScore, count); isize valid_count = 0; isize first_success_index = -1; for_array(i, t->Union.variants) { @@ -4739,7 +4736,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 gb_string_free(type_str); return false; } - gbAllocator a = c->allocator; + gbAllocator a = permanent_allocator(); Type *tuple = alloc_type_tuple(); @@ -5356,7 +5353,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 soa_struct->Struct.soa_elem = elem; soa_struct->Struct.soa_count = count; - scope = create_scope(c->scope, c->allocator); + scope = create_scope(c->scope); soa_struct->Struct.scope = scope; String params_xyzw[4] = { @@ -5389,7 +5386,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 soa_struct->Struct.soa_elem = elem; soa_struct->Struct.soa_count = count; - scope = create_scope(old_struct->Struct.scope->parent, c->allocator); + scope = create_scope(old_struct->Struct.scope->parent); soa_struct->Struct.scope = scope; for_array(i, old_struct->Struct.fields) { @@ -6539,11 +6536,11 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { bool show_error = show_error_mode == CallArgumentMode_ShowErrors; CallArgumentError err = CallArgumentError_None; + SCOPED_TEMPORARY_BLOCK(); + isize param_count = pt->param_count; - bool *visited = gb_alloc_array(c->allocator, bool, param_count); - defer (gb_free(c->allocator, visited)); - auto ordered_operands = array_make(c->allocator, param_count); - defer (array_free(&ordered_operands)); + bool *visited = gb_alloc_array(temporary_allocator(), bool, param_count); + auto ordered_operands = array_make(temporary_allocator(), param_count); defer ({ for_array(i, ordered_operands) { Operand const &o = ordered_operands[i]; @@ -7385,13 +7382,15 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper Array ordered_operands = operands; if (!named_fields) { - ordered_operands = array_make(c->allocator, param_count); + ordered_operands = array_make(permanent_allocator(), param_count); array_copy(&ordered_operands, operands, 0); } else { - bool *visited = gb_alloc_array(c->allocator, bool, param_count); + SCOPED_TEMPORARY_BLOCK(); + + bool *visited = gb_alloc_array(temporary_allocator(), bool, param_count); // LEAK(bill) - ordered_operands = array_make(c->allocator, param_count); + ordered_operands = array_make(permanent_allocator(), param_count); for_array(i, ce->args) { Ast *arg = ce->args[i]; @@ -7549,8 +7548,6 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper } { - gbAllocator a = c->allocator; - bool failure = false; Entity *found_entity = find_polymorphic_record_entity(c, original_type, param_count, ordered_operands, &failure); if (found_entity) { @@ -8213,7 +8210,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type Type *type = alloc_type(Type_Proc); check_open_scope(&ctx, pl->type); { - decl = make_decl_info(ctx.allocator, ctx.scope, ctx.decl); + decl = make_decl_info(ctx.scope, ctx.decl); decl->proc_lit = node; ctx.decl = decl; defer (ctx.decl = ctx.decl->parent); @@ -8510,7 +8507,9 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type } if (cl->elems[0]->kind == Ast_FieldValue) { - bool *fields_visited = gb_alloc_array(c->allocator, bool, field_count); + SCOPED_TEMPORARY_BLOCK(); + + bool *fields_visited = gb_alloc_array(temporary_allocator(), bool, field_count); for_array(i, cl->elems) { Ast *elem = cl->elems[i]; @@ -10092,7 +10091,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type error(x.expr, "Expected a constant string for the inline asm constraints parameter"); } - Scope *scope = create_scope(c->scope, heap_allocator()); + Scope *scope = create_scope(c->scope); scope->flags |= ScopeFlag_Proc; Type *params = alloc_type_tuple(); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index e6902f6a3..d722ea8ee 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -640,9 +640,10 @@ void add_constant_switch_case(CheckerContext *ctx, Map *seen, Oper HashKey key = hash_exact_value(operand.value); TypeAndToken *found = map_get(seen, key); if (found != nullptr) { + SCOPED_TEMPORARY_BLOCK(); + isize count = multi_map_count(seen, key); - TypeAndToken *taps = gb_alloc_array(ctx->allocator, TypeAndToken, count); - defer (gb_free(ctx->allocator, taps)); + TypeAndToken *taps = gb_alloc_array(temporary_allocator(), TypeAndToken, count); multi_map_get_all(seen, key, taps); for (isize i = 0; i < count; i++) { @@ -859,7 +860,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { token.pos = ast_token(ss->body).pos; token.string = str_lit("true"); - x.expr = gb_alloc_item(ctx->allocator, Ast); + x.expr = gb_alloc_item(permanent_allocator(), Ast); x.expr->kind = Ast_Ident; x.expr->Ident.token = token; } @@ -1025,8 +1026,8 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { GB_ASSERT(is_type_enum(et)); auto fields = et->Enum.fields; - auto unhandled = array_make(ctx->allocator, 0, fields.count); - defer (array_free(&unhandled)); + SCOPED_TEMPORARY_BLOCK(); + auto unhandled = array_make(temporary_allocator(), 0, fields.count); for_array(i, fields) { Entity *f = fields[i]; @@ -1265,8 +1266,8 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { GB_ASSERT(is_type_union(ut)); auto variants = ut->Union.variants; - auto unhandled = array_make(ctx->allocator, 0, variants.count); - defer (array_free(&unhandled)); + SCOPED_TEMPORARY_BLOCK(); + auto unhandled = array_make(temporary_allocator(), 0, variants.count); for_array(i, variants) { Type *t = variants[i]; @@ -1433,12 +1434,12 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { return; } + SCOPED_TEMPORARY_BLOCK(); + // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation - auto lhs_operands = array_make(ctx->allocator, lhs_count); - auto rhs_operands = array_make(ctx->allocator, 0, 2*lhs_count); - defer (array_free(&lhs_operands)); - defer (array_free(&rhs_operands)); + auto lhs_operands = array_make(temporary_allocator(), lhs_count); + auto rhs_operands = array_make(temporary_allocator(), 0, 2*lhs_count); for_array(i, as->lhs) { if (is_blank_ident(as->lhs[i])) { @@ -1462,8 +1463,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { } } - auto lhs_to_ignore = array_make(ctx->allocator, lhs_count); - defer (array_free(&lhs_to_ignore)); + auto lhs_to_ignore = array_make(temporary_allocator(), lhs_count); isize max = gb_min(lhs_count, rhs_count); // NOTE(bill, 2020-05-02): This is an utter hack to get these custom atom operations working @@ -1878,7 +1878,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { DeclInfo *d = decl_info_of_entity(e); GB_ASSERT(d == nullptr); add_entity(ctx->checker, ctx->scope, e->identifier, e); - d = make_decl_info(ctx->allocator, ctx->scope, ctx->decl); + d = make_decl_info(ctx->scope, ctx->decl); add_entity_and_decl_info(ctx, e->identifier, e, d); } @@ -2036,7 +2036,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { case_ast_node(vd, ValueDecl, node); if (vd->is_mutable) { - Entity **entities = gb_alloc_array(ctx->allocator, Entity *, vd->names.count); + Entity **entities = gb_alloc_array(permanent_allocator(), Entity *, vd->names.count); isize entity_count = 0; isize new_name_count = 0; diff --git a/src/check_type.cpp b/src/check_type.cpp index 6c9e82aa1..af0c70119 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -400,7 +400,7 @@ void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array< } } - auto entities = array_make(ctx->allocator, 0, variable_count); + auto entities = array_make(permanent_allocator(), 0, variable_count); for_array(i, params) { Ast *param = params[i]; @@ -596,7 +596,7 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array(ctx->allocator, 0, variant_count); + auto variants = array_make(permanent_allocator(), 0, variant_count); union_type->Union.scope = ctx->scope; @@ -618,7 +618,7 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array(ctx->allocator, 0, variable_count); + auto entities = array_make(permanent_allocator(), 0, variable_count); for_array(i, params) { Ast *param = params[i]; @@ -869,7 +869,7 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast enum_type->Enum.base_type = base_type; enum_type->Enum.scope = ctx->scope; - auto fields = array_make(ctx->allocator, 0, et->fields.count); + auto fields = array_make(permanent_allocator(), 0, et->fields.count); Type *constant_type = enum_type; if (named_type != nullptr) { @@ -986,9 +986,9 @@ void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, Ast *node) ast_node(bft, BitFieldType, node); GB_ASSERT(is_type_bit_field(bit_field_type)); - auto fields = array_make(ctx->allocator, 0, bft->fields.count); - auto sizes = array_make (ctx->allocator, 0, bft->fields.count); - auto offsets = array_make (ctx->allocator, 0, bft->fields.count); + auto fields = array_make(permanent_allocator(), 0, bft->fields.count); + auto sizes = array_make (permanent_allocator(), 0, bft->fields.count); + auto offsets = array_make (permanent_allocator(), 0, bft->fields.count); scope_reserve(ctx->scope, bft->fields.count); @@ -1549,7 +1549,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is bool is_variadic = false; isize variadic_index = -1; bool is_c_vararg = false; - auto variables = array_make(ctx->allocator, 0, variable_count); + auto variables = array_make(permanent_allocator(), 0, variable_count); for_array(i, params) { Ast *param = params[i]; if (param->kind != Ast_Field) { @@ -1891,7 +1891,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { } } - auto variables = array_make(ctx->allocator, 0, variable_count); + auto variables = array_make(permanent_allocator(), 0, variable_count); for_array(i, results) { ast_node(field, Field, results[i]); Ast *default_value = unparen_expr(field->default_value); @@ -2781,7 +2781,6 @@ void init_map_entry_type(Type *type) { // NOTE(bill): The preload types may have not been set yet GB_ASSERT(t_map_key != nullptr); - gbAllocator a = heap_allocator(); Type *entry_type = alloc_type_struct(); /* @@ -2793,9 +2792,9 @@ void init_map_entry_type(Type *type) { } */ Ast *dummy_node = alloc_ast_node(nullptr, Ast_Invalid); - Scope *s = create_scope(builtin_pkg->scope, a); + Scope *s = create_scope(builtin_pkg->scope); - auto fields = array_make(a, 0, 3); + auto fields = array_make(permanent_allocator(), 0, 3); array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("key")), t_map_key, false, 0, EntityState_Resolved)); array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("next")), t_int, false, 1, EntityState_Resolved)); array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("value")), type->Map.value, false, 2, EntityState_Resolved)); @@ -2803,7 +2802,6 @@ void init_map_entry_type(Type *type) { entry_type->Struct.fields = fields; - // type_set_offsets(a, entry_type); type->Map.entry_type = entry_type; } @@ -2826,15 +2824,14 @@ void init_map_internal_types(Type *type) { entries: [dynamic]EntryType; } */ - gbAllocator a = heap_allocator(); Ast *dummy_node = alloc_ast_node(nullptr, Ast_Invalid); - Scope *s = create_scope(builtin_pkg->scope, a); + Scope *s = create_scope(builtin_pkg->scope); Type *hashes_type = alloc_type_slice(t_int); Type *entries_type = alloc_type_dynamic_array(type->Map.entry_type); - auto fields = array_make(a, 0, 2); + auto fields = array_make(permanent_allocator(), 0, 2); array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved)); array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved)); @@ -2902,7 +2899,7 @@ Type *make_soa_struct_fixed(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_ soa_struct->Struct.soa_elem = elem; soa_struct->Struct.soa_count = count; - scope = create_scope(ctx->scope, ctx->allocator); + scope = create_scope(ctx->scope); soa_struct->Struct.scope = scope; String params_xyzw[4] = { @@ -2935,7 +2932,7 @@ Type *make_soa_struct_fixed(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_ soa_struct->Struct.soa_elem = elem; soa_struct->Struct.soa_count = count; - scope = create_scope(old_struct->Struct.scope->parent, ctx->allocator); + scope = create_scope(old_struct->Struct.scope->parent); soa_struct->Struct.scope = scope; for_array(i, old_struct->Struct.fields) { @@ -2996,7 +2993,7 @@ Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_ soa_struct->Struct.soa_count = 0; soa_struct->Struct.is_polymorphic = true; - scope = create_scope(ctx->scope, ctx->allocator); + scope = create_scope(ctx->scope); soa_struct->Struct.scope = scope; } else if (is_type_array(elem)) { Type *old_array = base_type(elem); @@ -3010,7 +3007,7 @@ Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_ soa_struct->Struct.soa_elem = elem; soa_struct->Struct.soa_count = 0; - scope = create_scope(ctx->scope, ctx->allocator); + scope = create_scope(ctx->scope); soa_struct->Struct.scope = scope; String params_xyzw[4] = { @@ -3046,7 +3043,7 @@ Type *make_soa_struct_slice(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_ soa_struct->Struct.soa_elem = elem; soa_struct->Struct.soa_count = 0; - scope = create_scope(old_struct->Struct.scope->parent, ctx->allocator); + scope = create_scope(old_struct->Struct.scope->parent); soa_struct->Struct.scope = scope; for_array(i, old_struct->Struct.fields) { @@ -3113,7 +3110,7 @@ Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, As soa_struct->Struct.soa_count = 0; soa_struct->Struct.is_polymorphic = true; - scope = create_scope(ctx->scope, ctx->allocator); + scope = create_scope(ctx->scope); soa_struct->Struct.scope = scope; } else if (is_type_array(elem)) { Type *old_array = base_type(elem); @@ -3127,7 +3124,7 @@ Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, As soa_struct->Struct.soa_elem = elem; soa_struct->Struct.soa_count = 0; - scope = create_scope(ctx->scope, ctx->allocator); + scope = create_scope(ctx->scope); soa_struct->Struct.scope = scope; String params_xyzw[4] = { @@ -3162,7 +3159,7 @@ Type *make_soa_struct_dynamic_array(CheckerContext *ctx, Ast *array_typ_expr, As soa_struct->Struct.soa_elem = elem; soa_struct->Struct.soa_count = 0; - scope = create_scope(old_struct->Struct.scope->parent, ctx->allocator); + scope = create_scope(old_struct->Struct.scope->parent); soa_struct->Struct.scope = scope; for_array(i, old_struct->Struct.fields) { diff --git a/src/checker.cpp b/src/checker.cpp index a07a3ffbe..76d8cceb3 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -187,8 +187,8 @@ void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) { array_init (&d->labels, heap_allocator()); } -DeclInfo *make_decl_info(gbAllocator a, Scope *scope, DeclInfo *parent) { - DeclInfo *d = gb_alloc_item(a, DeclInfo); +DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) { + DeclInfo *d = gb_alloc_item(permanent_allocator(), DeclInfo); init_decl_info(d, scope, parent); return d; } @@ -219,8 +219,8 @@ bool decl_info_has_init(DeclInfo *d) { -Scope *create_scope(Scope *parent, gbAllocator allocator, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { - Scope *s = gb_alloc_item(allocator, Scope); +Scope *create_scope(Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { + Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; string_map_init(&s->elements, heap_allocator(), init_elements_capacity); ptr_set_init(&s->imported, heap_allocator(), 0); @@ -244,7 +244,7 @@ Scope *create_scope_from_file(CheckerContext *c, AstFile *f) { GB_ASSERT(f->pkg != nullptr); GB_ASSERT(f->pkg->scope != nullptr); - Scope *s = create_scope(f->pkg->scope, c->allocator); + Scope *s = create_scope(f->pkg->scope); array_reserve(&s->delayed_imports, f->imports.count); array_reserve(&s->delayed_directives, f->directive_count); @@ -264,7 +264,7 @@ Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) { decl_count += pkg->files[i]->decls.count; } isize init_elements_capacity = 2*decl_count; - Scope *s = create_scope(builtin_pkg->scope, c->allocator, init_elements_capacity); + Scope *s = create_scope(builtin_pkg->scope, init_elements_capacity); s->flags |= ScopeFlag_Pkg; s->pkg = pkg; @@ -324,7 +324,7 @@ void check_open_scope(CheckerContext *c, Ast *node) { GB_ASSERT(node->kind == Ast_Invalid || is_ast_stmt(node) || is_ast_type(node)); - Scope *scope = create_scope(c->scope, c->allocator); + Scope *scope = create_scope(c->scope); add_scope(c, node, scope); switch (node->kind) { case Ast_ProcType: @@ -699,7 +699,7 @@ void init_universal(void) { builtin_pkg->name = str_lit("builtin"); builtin_pkg->kind = Package_Normal; - builtin_pkg->scope = create_scope(nullptr, a); + builtin_pkg->scope = create_scope(nullptr); builtin_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; builtin_pkg->scope->pkg = builtin_pkg; @@ -707,7 +707,7 @@ void init_universal(void) { intrinsics_pkg->name = str_lit("intrinsics"); intrinsics_pkg->kind = Package_Normal; - intrinsics_pkg->scope = create_scope(nullptr, a); + intrinsics_pkg->scope = create_scope(nullptr); intrinsics_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; intrinsics_pkg->scope->pkg = intrinsics_pkg; @@ -715,7 +715,7 @@ void init_universal(void) { config_pkg->name = str_lit("config"); config_pkg->kind = Package_Normal; - config_pkg->scope = create_scope(nullptr, a); + config_pkg->scope = create_scope(nullptr); config_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; config_pkg->scope->pkg = config_pkg; @@ -872,7 +872,6 @@ CheckerContext make_checker_context(Checker *c) { CheckerContext ctx = c->init_ctx; ctx.checker = c; ctx.info = &c->info; - ctx.allocator = c->allocator; ctx.scope = builtin_pkg->scope; ctx.pkg = builtin_pkg; @@ -906,8 +905,6 @@ bool init_checker(Checker *c, Parser *parser) { isize total_token_count = c->parser->total_token_count; isize arena_size = 2 * item_size * total_token_count; - c->allocator = heap_allocator(); - c->init_ctx = make_checker_context(c); return true; } @@ -2597,7 +2594,7 @@ DECL_ATTRIBUTE_PROC(type_decl_attribute) { if (valid && build_context.use_llvm_api) { if (ac->atom_op_table == nullptr) { - ac->atom_op_table = gb_alloc_item(heap_allocator(), TypeAtomOpTable); + ac->atom_op_table = gb_alloc_item(permanent_allocator(), TypeAtomOpTable); } ac->atom_op_table->op[TypeAtomOp_index_get] = e; } @@ -2656,7 +2653,7 @@ DECL_ATTRIBUTE_PROC(type_decl_attribute) { if (valid && build_context.use_llvm_api) { if (ac->atom_op_table == nullptr) { - ac->atom_op_table = gb_alloc_item(heap_allocator(), TypeAtomOpTable); + ac->atom_op_table = gb_alloc_item(permanent_allocator(), TypeAtomOpTable); } ac->atom_op_table->op[TypeAtomOp_index_set] = e; } @@ -2738,7 +2735,7 @@ DECL_ATTRIBUTE_PROC(type_decl_attribute) { if (valid && build_context.use_llvm_api) { if (ac->atom_op_table == nullptr) { - ac->atom_op_table = gb_alloc_item(heap_allocator(), TypeAtomOpTable); + ac->atom_op_table = gb_alloc_item(permanent_allocator(), TypeAtomOpTable); } ac->atom_op_table->op[TypeAtomOp_slice] = e; } @@ -3090,7 +3087,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } Ast *init_expr = value; - DeclInfo *d = make_decl_info(heap_allocator(), c->scope, c->decl); + DeclInfo *d = make_decl_info(c->scope, c->decl); d->entity = e; d->type_expr = vd->type; d->init_expr = init_expr; @@ -3118,7 +3115,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { Token token = name->Ident.token; Ast *fl = c->foreign_context.curr_library; - DeclInfo *d = make_decl_info(c->allocator, c->scope, c->decl); + DeclInfo *d = make_decl_info(c->scope, c->decl); Entity *e = nullptr; d->attributes = vd->attributes; @@ -4317,7 +4314,7 @@ void check_parsed_files(Checker *c) { for_array(i, c->parser->packages) { AstPackage *p = c->parser->packages[i]; Scope *scope = create_scope_from_package(&c->init_ctx, p); - p->decl_info = make_decl_info(c->allocator, scope, c->init_ctx.decl); + p->decl_info = make_decl_info(scope, c->init_ctx.decl); string_map_set(&c->info.packages, p->fullpath, p); if (scope->flags&ScopeFlag_Init) { diff --git a/src/checker.hpp b/src/checker.hpp index 88e9451ee..ed4809748 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -301,7 +301,6 @@ struct CheckerContext { ProcCallingConvention curr_proc_calling_convention; bool in_proc_sig; ForeignContext foreign_context; - gbAllocator allocator; CheckerTypePath *type_path; isize type_level; // TODO(bill): Actually handle correctly @@ -331,7 +330,6 @@ struct Checker { Array procs_with_deferred_to_check; CheckerContext *curr_ctx; - gbAllocator allocator; CheckerContext init_ctx; }; diff --git a/src/common.cpp b/src/common.cpp index 567655c04..05ebdd4c5 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -451,7 +451,6 @@ void arena_free_all(Arena *arena) { - GB_ALLOCATOR_PROC(arena_allocator_proc); gbAllocator arena_allocator(Arena *arena) { @@ -492,6 +491,38 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) { return ptr; } +struct SCOPED_TEMP_ARENA_MEMORY { + Arena *arena; + u8 * ptr; + u8 * end; + u8 * prev; + isize total_used; + isize block_count; + + SCOPED_TEMP_ARENA_MEMORY(Arena *the_arena) { + GB_ASSERT(!the_arena->use_mutex); + arena = the_arena; + ptr = arena->ptr; + end = arena->end; + prev = arena->prev; + total_used = arena->total_used; + block_count = arena->blocks.count; + } + ~SCOPED_TEMP_ARENA_MEMORY() { + if (arena->blocks.count != block_count) { + for (isize i = block_count; i < arena->blocks.count; i++) { + gb_free(arena->backing, arena->blocks[i]); + } + arena->blocks.count = block_count; + } + arena->ptr = ptr; + arena->end = end; + arena->prev = prev; + arena->total_used = total_used; + } +}; + + gb_global Arena permanent_arena = {}; @@ -504,6 +535,8 @@ gbAllocator temporary_allocator() { return arena_allocator(&temporary_arena); } +#define SCOPED_TEMPORARY_BLOCK() auto GB_DEFER_3(_SCOPED_TEMPORARY_BLOCK_) = SCOPED_TEMP_ARENA_MEMORY(&temporary_arena) + diff --git a/src/gb/gb.h b/src/gb/gb.h index 848f27628..f13693000 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -5156,7 +5156,7 @@ b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) { index = core * a->threads_per_core + thread_index; thread = pthread_self(); - + cpuset_t mn; CPU_ZERO(&mn); diff --git a/src/ir.cpp b/src/ir.cpp index ee177edd6..7b6301e30 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2132,7 +2132,7 @@ irDebugInfo *ir_add_debug_info_field(irModule *module, irDebugInfo *scope, Entit if (e->token.string.len == 0) { // If no name available for field, use its field index as its name. isize max_len = 8; - u8 *str = cast(u8 *)gb_alloc_array(heap_allocator(), u8, max_len); + u8 *str = cast(u8 *)gb_alloc_array(permanent_allocator(), u8, max_len); isize len = gb_snprintf(cast(char *)str, 8, "%d", index); di->DerivedType.name = make_string(str, len-1); } @@ -3293,7 +3293,7 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array const &ar GB_ASSERT_MSG(param_count == args.count, "%.*s %td == %td", LIT(p->entity->token.string), param_count, args.count); } - auto processed_args = array_make(heap_allocator(), 0, args.count); + auto processed_args = array_make(permanent_allocator(), 0, args.count); for (isize i = 0; i < param_count; i++) { Entity *e = pt->Proc.params->Tuple.variables[i]; @@ -3416,7 +3416,7 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array const &ar case DeferredProcedure_in_out: { auto out_args = ir_value_to_array(p, result); - array_init(&result_as_args, heap_allocator(), in_args.count + out_args.count); + array_init(&result_as_args, permanent_allocator(), in_args.count + out_args.count); array_copy(&result_as_args, in_args, 0); array_copy(&result_as_args, out_args, in_args.count); } @@ -4537,7 +4537,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * Type *ft = base_complex_elem_type(t_left); if (op == Token_Quo) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; @@ -4615,7 +4615,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * return ir_emit_load(proc, res); } else if (op == Token_Mul) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; @@ -4625,7 +4625,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * default: GB_PANIC("Unknown float type"); break; } } else if (op == Token_Quo) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = left; args[1] = right; @@ -4828,7 +4828,7 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue irValue *invalid_typeid = ir_value_constant(t_typeid, exact_value_i64(0)); return ir_emit_comp(proc, op_kind, x, invalid_typeid); } else if (is_type_bit_field(t)) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); irValue *lhs = ir_address_from_load_or_generate_local(proc, x); args[0] = ir_emit_conv(proc, lhs, t_rawptr); args[1] = ir_const_int(type_size_of(t)); @@ -4848,7 +4848,7 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue return ir_emit_comp(proc, op_kind, cap, v_zero); } } else if (is_type_struct(t) && type_has_nil(t)) { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); irValue *lhs = ir_address_from_load_or_generate_local(proc, x); args[0] = ir_emit_conv(proc, lhs, t_rawptr); args[1] = ir_const_int(type_size_of(t)); @@ -4966,7 +4966,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal } else { if (is_type_simple_compare(tl) && (op_kind == Token_CmpEq || op_kind == Token_NotEq)) { // TODO(bill): Test to see if this is actually faster!!!! - auto args = array_make(heap_allocator(), 3); + auto args = array_make(permanent_allocator(), 3); args[0] = ir_emit_conv(proc, lhs, t_rawptr); args[1] = ir_emit_conv(proc, rhs, t_rawptr); args[2] = ir_const_int(type_size_of(tl)); @@ -7355,7 +7355,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, Ast *expr, TypeAndValue tv, Bu // "Intrinsics" case BuiltinProc_alloca: { - auto args = array_make(heap_allocator(), 2); + auto args = array_make(permanent_allocator(), 2); args[0] = ir_emit_conv(proc, ir_build_expr(proc, ce->args[0]), t_i32); args[1] = ir_build_expr(proc, ce->args[1]); return ir_emit(proc, ir_instr_inline_code(proc, id, args, t_u8_ptr)); @@ -9024,8 +9024,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) { if (cl->elems.count > 0) { ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr))); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks for_array(i, cl->elems) { @@ -9123,8 +9122,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) { if (cl->elems.count > 0) { ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr))); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks for_array(i, cl->elems) { @@ -9232,8 +9230,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) { irValue *data = ir_emit_array_ep(proc, slice->ConstantSlice.backing_array, v_zero32); - auto temp_data = array_make(heap_allocator(), 0, cl->elems.count); - defer (array_free(&temp_data)); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); for_array(i, cl->elems) { Ast *elem = cl->elems[i]; @@ -10179,7 +10176,7 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { String mangled_name = {}; { - gbString str = gb_string_make_length(heap_allocator(), proc->name.text, proc->name.len); + gbString str = gb_string_make_length(permanent_allocator(), proc->name.text, proc->name.len); str = gb_string_appendc(str, "-"); str = gb_string_append_fmt(str, ".%.*s-%llu", LIT(name), cast(long long)e->id); mangled_name.text = cast(u8 *)str; diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 2d15f176b..1a306365f 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -76,7 +76,8 @@ void ir_write_u64(irFileBuffer *f, u64 i) { } void ir_write_big_int(irFileBuffer *f, BigInt const &x, Type *type, bool swap_endian) { if (x.len == 2) { - gbAllocator a = heap_allocator(); // TODO(bill): Change this allocator + SCOPED_TEMPORARY_BLOCK(); + u64 words[2] = {}; BigInt y = x; if (swap_endian) { @@ -88,9 +89,8 @@ void ir_write_big_int(irFileBuffer *f, BigInt const &x, Type *type, bool swap_en y.d.words = words; } - String s = big_int_to_string(a, &y, 10); + String s = big_int_to_string(temporary_allocator(), &y, 10); ir_write_string(f, s); - gb_free(a, s.text); } else { i64 i = 0; if (x.neg) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 121917740..0e0fa904b 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -781,6 +781,8 @@ void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) { + SCOPED_TEMPORARY_BLOCK(); + unsigned field_count = LLVMCountStructElementTypes(src); LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); LLVMGetStructElementTypes(src, fields); @@ -1277,9 +1279,10 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { m->internal_type_level += 1; defer (m->internal_type_level -= 1); + SCOPED_TEMPORARY_BLOCK(); + unsigned field_count = cast(unsigned)(type->Struct.fields.count + offset); LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); - GB_ASSERT(fields != nullptr); for_array(i, type->Struct.fields) { Entity *field = type->Struct.fields[i]; @@ -1338,6 +1341,8 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { if (type->Tuple.variables.count == 1) { return lb_type(m, type->Tuple.variables[0]->type); } else { + SCOPED_TEMPORARY_BLOCK(); + unsigned field_count = cast(unsigned)(type->Tuple.variables.count); LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); @@ -1437,6 +1442,8 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { extra_param_count += 1; } + SCOPED_TEMPORARY_BLOCK(); + isize param_count = type->Proc.abi_compat_params.count + extra_param_count; auto param_types = array_make(temporary_allocator(), 0, param_count); @@ -1483,6 +1490,8 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { { LLVMTypeRef internal_type = nullptr; { + SCOPED_TEMPORARY_BLOCK(); + GB_ASSERT(type->BitField.fields.count == type->BitField.sizes.count); unsigned field_count = cast(unsigned)type->BitField.fields.count; LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); @@ -5279,8 +5288,9 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc return lb_const_nil(m, original_type); } if (cl->elems[0]->kind == Ast_FieldValue) { - // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand + SCOPED_TEMPORARY_BLOCK(); + // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count); isize value_index = 0; @@ -5338,6 +5348,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } else { GB_ASSERT_MSG(elem_count == type->Array.count, "%td != %td", elem_count, type->Array.count); + SCOPED_TEMPORARY_BLOCK(); LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count); for (isize i = 0; i < elem_count; i++) { @@ -5360,8 +5371,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc return lb_const_nil(m, original_type); } if (cl->elems[0]->kind == Ast_FieldValue) { + SCOPED_TEMPORARY_BLOCK(); // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand - LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count); isize value_index = 0; @@ -5423,6 +5434,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } else { GB_ASSERT_MSG(elem_count == type->EnumeratedArray.count, "%td != %td", elem_count, type->EnumeratedArray.count); + SCOPED_TEMPORARY_BLOCK(); LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count); for (isize i = 0; i < elem_count; i++) { @@ -5447,6 +5459,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } GB_ASSERT(elem_type_can_be_constant(elem_type)); + SCOPED_TEMPORARY_BLOCK(); + isize total_elem_count = type->SimdVector.count; LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, total_elem_count); @@ -5473,6 +5487,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc offset = 1; } + SCOPED_TEMPORARY_BLOCK(); + isize value_count = type->Struct.fields.count + offset; LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count); bool *visited = gb_alloc_array(temporary_allocator(), bool, value_count); @@ -10880,6 +10896,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); + SCOPED_TEMPORARY_BLOCK(); auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks @@ -10979,6 +10996,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); + SCOPED_TEMPORARY_BLOCK(); auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks @@ -11087,6 +11105,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { lbValue data = lb_slice_elem(p, slice); + SCOPED_TEMPORARY_BLOCK(); auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); for_array(i, cl->elems) { @@ -11935,6 +11954,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da str_lit("$enum_values"), cast(i64)entry_index); + SCOPED_TEMPORARY_BLOCK(); LLVMValueRef *name_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count); LLVMValueRef *value_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count); @@ -12894,7 +12914,7 @@ void lb_generate_code(lbGenerator *gen) { } - String filepath_ll = concatenate_strings(temporary_allocator(), gen->output_base, STR_LIT(".ll")); + String filepath_ll = concatenate_strings(permanent_allocator(), gen->output_base, STR_LIT(".ll")); TIME_SECTION("LLVM Procedure Generation"); for_array(i, m->procedures_to_generate) { diff --git a/src/main.cpp b/src/main.cpp index d0d2e2bbb..2dbac3390 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1646,6 +1646,7 @@ int main(int arg_count, char const **arg_ptr) { arena_init(&permanent_arena, heap_allocator()); arena_init(&temporary_arena, heap_allocator()); arena_init(&global_ast_arena, heap_allocator()); + permanent_arena.use_mutex = true; init_string_buffer_memory(); init_string_interner(); -- cgit v1.2.3 From 0d6f5cec37e8815ff2e1c82575a05db98e4043d4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 Nov 2020 19:36:37 +0000 Subject: Implement custom temporary allocator using ring buffer --- src/check_decl.cpp | 1 - src/check_expr.cpp | 9 ---- src/check_stmt.cpp | 5 -- src/common.cpp | 130 +++++++++++++++++++++++++++++++++++++-------------- src/ir_print.cpp | 2 - src/llvm_backend.cpp | 24 ---------- src/main.cpp | 14 +++--- 7 files changed, 101 insertions(+), 84 deletions(-) (limited to 'src/main.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index bfe703853..248069b97 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -121,7 +121,6 @@ void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Ar // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation - SCOPED_TEMPORARY_BLOCK(); auto operands = array_make(temporary_allocator(), 0, 2*lhs_count); check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 755ceb634..110e83ef2 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1832,7 +1832,6 @@ void check_comparison(CheckerContext *c, Operand *x, Operand *y, TokenKind op) { } - SCOPED_TEMPORARY_BLOCK(); gbString err_str = nullptr; if (check_is_assignable_to(c, x, y->type) || @@ -2974,8 +2973,6 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { case Type_Union: if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) { - SCOPED_TEMPORARY_BLOCK(); - isize count = t->Union.variants.count; ValidIndexAndScore *valids = gb_alloc_array(temporary_allocator(), ValidIndexAndScore, count); isize valid_count = 0; @@ -6536,8 +6533,6 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { bool show_error = show_error_mode == CallArgumentMode_ShowErrors; CallArgumentError err = CallArgumentError_None; - SCOPED_TEMPORARY_BLOCK(); - isize param_count = pt->param_count; bool *visited = gb_alloc_array(temporary_allocator(), bool, param_count); auto ordered_operands = array_make(temporary_allocator(), param_count); @@ -7385,8 +7380,6 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper ordered_operands = array_make(permanent_allocator(), param_count); array_copy(&ordered_operands, operands, 0); } else { - SCOPED_TEMPORARY_BLOCK(); - bool *visited = gb_alloc_array(temporary_allocator(), bool, param_count); // LEAK(bill) @@ -8507,8 +8500,6 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type } if (cl->elems[0]->kind == Ast_FieldValue) { - SCOPED_TEMPORARY_BLOCK(); - bool *fields_visited = gb_alloc_array(temporary_allocator(), bool, field_count); for_array(i, cl->elems) { diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index d722ea8ee..a480e0fdf 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -640,8 +640,6 @@ void add_constant_switch_case(CheckerContext *ctx, Map *seen, Oper HashKey key = hash_exact_value(operand.value); TypeAndToken *found = map_get(seen, key); if (found != nullptr) { - SCOPED_TEMPORARY_BLOCK(); - isize count = multi_map_count(seen, key); TypeAndToken *taps = gb_alloc_array(temporary_allocator(), TypeAndToken, count); @@ -1026,7 +1024,6 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { GB_ASSERT(is_type_enum(et)); auto fields = et->Enum.fields; - SCOPED_TEMPORARY_BLOCK(); auto unhandled = array_make(temporary_allocator(), 0, fields.count); for_array(i, fields) { @@ -1266,7 +1263,6 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { GB_ASSERT(is_type_union(ut)); auto variants = ut->Union.variants; - SCOPED_TEMPORARY_BLOCK(); auto unhandled = array_make(temporary_allocator(), 0, variants.count); for_array(i, variants) { @@ -1434,7 +1430,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { return; } - SCOPED_TEMPORARY_BLOCK(); // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation diff --git a/src/common.cpp b/src/common.cpp index 05ebdd4c5..0147f27d5 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -56,6 +56,14 @@ gb_inline isize align_formula_isize(isize size, isize align) { } return size; } +gb_inline void *align_formula_ptr(void *ptr, isize align) { + if (align > 0) { + uintptr result = (cast(uintptr)ptr) + align-1; + return (void *)(result - result%align); + } + return ptr; +} + GB_ALLOCATOR_PROC(heap_allocator_proc); @@ -380,6 +388,9 @@ typedef struct Arena { #define ARENA_MIN_ALIGNMENT 16 #define ARENA_DEFAULT_BLOCK_SIZE (8*1024*1024) + +gb_global Arena permanent_arena = {}; + void arena_init(Arena *arena, gbAllocator backing, isize block_size=ARENA_DEFAULT_BLOCK_SIZE) { arena->backing = backing; arena->block_size = block_size; @@ -491,51 +502,98 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) { return ptr; } -struct SCOPED_TEMP_ARENA_MEMORY { - Arena *arena; - u8 * ptr; - u8 * end; - u8 * prev; - isize total_used; - isize block_count; - - SCOPED_TEMP_ARENA_MEMORY(Arena *the_arena) { - GB_ASSERT(!the_arena->use_mutex); - arena = the_arena; - ptr = arena->ptr; - end = arena->end; - prev = arena->prev; - total_used = arena->total_used; - block_count = arena->blocks.count; - } - ~SCOPED_TEMP_ARENA_MEMORY() { - if (arena->blocks.count != block_count) { - for (isize i = block_count; i < arena->blocks.count; i++) { - gb_free(arena->backing, arena->blocks[i]); - } - arena->blocks.count = block_count; - } - arena->ptr = ptr; - arena->end = end; - arena->prev = prev; - arena->total_used = total_used; - } + +gbAllocator permanent_allocator() { + return arena_allocator(&permanent_arena); + // return heap_allocator(); +} + + + +struct Temp_Allocator { + u8 *data; + isize len; + isize curr_offset; + gbAllocator backup_allocator; + Array leaked_allocations; }; +gb_global Temp_Allocator temporary_allocator_data = {}; +void temp_allocator_init(Temp_Allocator *s, isize size) { + s->backup_allocator = heap_allocator(); + s->data = cast(u8 *)gb_alloc_align(s->backup_allocator, size, 16); + s->curr_offset = 0; + s->leaked_allocations.allocator = s->backup_allocator; +} +void *temp_allocator_alloc(Temp_Allocator *s, isize size, isize alignment) { + size = align_formula_isize(size, alignment); + if (s->curr_offset+size <= s->len) { + u8 *start = s->data; + u8 *ptr = start + s->curr_offset; + ptr = cast(u8 *)align_formula_ptr(ptr, alignment); + // assume memory is zero + + isize offset = ptr - start; + s->curr_offset = offset + size; + return ptr; + } else if (size <= s->len) { + u8 *start = s->data; + u8 *ptr = cast(u8 *)align_formula_ptr(start, alignment); + // assume memory is zero + + isize offset = ptr - start; + s->curr_offset = offset + size; + return ptr; + } -gb_global Arena permanent_arena = {}; -gb_global Arena temporary_arena = {}; + void *ptr = gb_alloc_align(s->backup_allocator, size, alignment); + array_add(&s->leaked_allocations, ptr); + return ptr; +} -gbAllocator permanent_allocator() { - return arena_allocator(&permanent_arena); +void temp_allocator_free_all(Temp_Allocator *s) { + s->curr_offset = 0; + for_array(i, s->leaked_allocations) { + gb_free(s->backup_allocator, s->leaked_allocations[i]); + } + array_clear(&s->leaked_allocations); + gb_zero_size(s->data, s->len); } -gbAllocator temporary_allocator() { - return arena_allocator(&temporary_arena); + +GB_ALLOCATOR_PROC(temp_allocator_proc) { + void *ptr = nullptr; + Temp_Allocator *s = cast(Temp_Allocator *)allocator_data; + GB_ASSERT_NOT_NULL(s); + + switch (type) { + case gbAllocation_Alloc: + return temp_allocator_alloc(s, size, alignment); + case gbAllocation_Free: + break; + case gbAllocation_Resize: + if (size == 0) { + ptr = nullptr; + } else if (size <= old_size) { + ptr = old_memory; + } else { + ptr = temp_allocator_alloc(s, size, alignment); + gb_memmove(ptr, old_memory, old_size); + } + break; + case gbAllocation_FreeAll: + temp_allocator_free_all(s); + break; + } + + return ptr; } -#define SCOPED_TEMPORARY_BLOCK() auto GB_DEFER_3(_SCOPED_TEMPORARY_BLOCK_) = SCOPED_TEMP_ARENA_MEMORY(&temporary_arena) + +gbAllocator temporary_allocator() { + return {temp_allocator_proc, &temporary_allocator_data}; +} diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 1a306365f..0605058ee 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -76,8 +76,6 @@ void ir_write_u64(irFileBuffer *f, u64 i) { } void ir_write_big_int(irFileBuffer *f, BigInt const &x, Type *type, bool swap_endian) { if (x.len == 2) { - SCOPED_TEMPORARY_BLOCK(); - u64 words[2] = {}; BigInt y = x; if (swap_endian) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 0e0fa904b..9eb641716 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -781,8 +781,6 @@ void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) { - SCOPED_TEMPORARY_BLOCK(); - unsigned field_count = LLVMCountStructElementTypes(src); LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); LLVMGetStructElementTypes(src, fields); @@ -1279,8 +1277,6 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { m->internal_type_level += 1; defer (m->internal_type_level -= 1); - SCOPED_TEMPORARY_BLOCK(); - unsigned field_count = cast(unsigned)(type->Struct.fields.count + offset); LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); @@ -1341,8 +1337,6 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { if (type->Tuple.variables.count == 1) { return lb_type(m, type->Tuple.variables[0]->type); } else { - SCOPED_TEMPORARY_BLOCK(); - unsigned field_count = cast(unsigned)(type->Tuple.variables.count); LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); @@ -1442,8 +1436,6 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { extra_param_count += 1; } - SCOPED_TEMPORARY_BLOCK(); - isize param_count = type->Proc.abi_compat_params.count + extra_param_count; auto param_types = array_make(temporary_allocator(), 0, param_count); @@ -1490,8 +1482,6 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { { LLVMTypeRef internal_type = nullptr; { - SCOPED_TEMPORARY_BLOCK(); - GB_ASSERT(type->BitField.fields.count == type->BitField.sizes.count); unsigned field_count = cast(unsigned)type->BitField.fields.count; LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count); @@ -5288,8 +5278,6 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc return lb_const_nil(m, original_type); } if (cl->elems[0]->kind == Ast_FieldValue) { - SCOPED_TEMPORARY_BLOCK(); - // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count); @@ -5348,7 +5336,6 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } else { GB_ASSERT_MSG(elem_count == type->Array.count, "%td != %td", elem_count, type->Array.count); - SCOPED_TEMPORARY_BLOCK(); LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count); for (isize i = 0; i < elem_count; i++) { @@ -5371,7 +5358,6 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc return lb_const_nil(m, original_type); } if (cl->elems[0]->kind == Ast_FieldValue) { - SCOPED_TEMPORARY_BLOCK(); // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count); @@ -5434,7 +5420,6 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } else { GB_ASSERT_MSG(elem_count == type->EnumeratedArray.count, "%td != %td", elem_count, type->EnumeratedArray.count); - SCOPED_TEMPORARY_BLOCK(); LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count); for (isize i = 0; i < elem_count; i++) { @@ -5459,8 +5444,6 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } GB_ASSERT(elem_type_can_be_constant(elem_type)); - SCOPED_TEMPORARY_BLOCK(); - isize total_elem_count = type->SimdVector.count; LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, total_elem_count); @@ -5487,13 +5470,10 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc offset = 1; } - SCOPED_TEMPORARY_BLOCK(); - isize value_count = type->Struct.fields.count + offset; LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count); bool *visited = gb_alloc_array(temporary_allocator(), bool, value_count); - if (cl->elems.count > 0) { if (cl->elems[0]->kind == Ast_FieldValue) { isize elem_count = cl->elems.count; @@ -10896,7 +10876,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); - SCOPED_TEMPORARY_BLOCK(); auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks @@ -10996,7 +10975,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { if (cl->elems.count > 0) { lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr))); - SCOPED_TEMPORARY_BLOCK(); auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); // NOTE(bill): Separate value, gep, store into their own chunks @@ -11105,7 +11083,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { lbValue data = lb_slice_elem(p, slice); - SCOPED_TEMPORARY_BLOCK(); auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); for_array(i, cl->elems) { @@ -11954,7 +11931,6 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da str_lit("$enum_values"), cast(i64)entry_index); - SCOPED_TEMPORARY_BLOCK(); LLVMValueRef *name_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count); LLVMValueRef *value_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count); diff --git a/src/main.cpp b/src/main.cpp index 2dbac3390..97fecb094 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1644,7 +1644,7 @@ int main(int arg_count, char const **arg_ptr) { defer (timings_destroy(timings)); arena_init(&permanent_arena, heap_allocator()); - arena_init(&temporary_arena, heap_allocator()); + temp_allocator_init(&temporary_allocator_data, 16*1024*1024); arena_init(&global_ast_arena, heap_allocator()); permanent_arena.use_mutex = true; @@ -1799,7 +1799,7 @@ int main(int arg_count, char const **arg_ptr) { return 1; } - arena_free_all(&temporary_arena); + temp_allocator_free_all(&temporary_allocator_data); if (build_context.generate_docs) { // generate_documentation(&parser); @@ -1818,7 +1818,7 @@ int main(int arg_count, char const **arg_ptr) { check_parsed_files(&checker); } - arena_free_all(&temporary_arena); + temp_allocator_free_all(&temporary_allocator_data); if (build_context.no_output_files) { if (build_context.query_data_set_settings.ok) { @@ -1849,7 +1849,7 @@ int main(int arg_count, char const **arg_ptr) { } lb_generate_code(&gen); - arena_free_all(&temporary_arena); + temp_allocator_free_all(&temporary_allocator_data); switch (build_context.build_mode) { case BuildMode_Executable: @@ -1928,17 +1928,17 @@ int main(int arg_count, char const **arg_ptr) { timings_start_section(timings, str_lit("llvm ir gen")); ir_gen_tree(&ir_gen); - arena_free_all(&temporary_arena); + temp_allocator_free_all(&temporary_allocator_data); timings_start_section(timings, str_lit("llvm ir opt tree")); ir_opt_tree(&ir_gen); - arena_free_all(&temporary_arena); + temp_allocator_free_all(&temporary_allocator_data); timings_start_section(timings, str_lit("llvm ir print")); print_llvm_ir(&ir_gen); - arena_free_all(&temporary_arena); + temp_allocator_free_all(&temporary_allocator_data); String output_name = ir_gen.output_name; -- cgit v1.2.3 From 939878df50cf314dd2cd0e5da737ac93e88b5b25 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 Nov 2020 23:54:18 +0000 Subject: Improve logic for x->y() shorthand --- src/check_expr.cpp | 16 ++++++++++++++++ src/check_stmt.cpp | 3 +-- src/checker.hpp | 3 ++- src/main.cpp | 3 --- src/parser.cpp | 24 ++++++++++++------------ 5 files changed, 31 insertions(+), 18 deletions(-) (limited to 'src/main.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 110e83ef2..11ccf2dab 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3437,6 +3437,13 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ Entity *entity = nullptr; Selection sel = {}; // NOTE(bill): Not used if it's an import name + if (!c->allow_arrow_right_selector_expr && se->token.kind == Token_ArrowRight) { + error(node, "Illegal use of -> selector shorthand outside of a call"); + operand->mode = Addressing_Invalid; + operand->expr = node; + return nullptr; + } + operand->expr = node; Ast *op_expr = se->expr; @@ -9492,8 +9499,13 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type // // NOTE(bill, 2020-05-22): I'm going to regret this decision, ain't I? + bool allow_arrow_right_selector_expr; + allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; + c->allow_arrow_right_selector_expr = true; Operand x = {}; ExprKind kind = check_expr_base(c, &x, se->expr, nullptr); + c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; + if (x.mode == Addressing_Invalid || x.type == t_invalid) { o->mode = Addressing_Invalid; o->type = t_invalid; @@ -9594,7 +9606,11 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type ce->args = modified_args; se->modified_call = true; + allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; + c->allow_arrow_right_selector_expr = true; check_expr_base(c, o, se->call, type_hint); + c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; + o->expr = node; return Expr_Expr; case_end; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index a480e0fdf..4cafa8df5 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -858,8 +858,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { token.pos = ast_token(ss->body).pos; token.string = str_lit("true"); - x.expr = gb_alloc_item(permanent_allocator(), Ast); - x.expr->kind = Ast_Ident; + x.expr = alloc_ast_node(nullptr, Ast_Ident); x.expr->Ident.token = token; } diff --git a/src/checker.hpp b/src/checker.hpp index ed4809748..e6111d2af 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -45,7 +45,7 @@ enum StmtFlag { Stmt_TypeSwitch = 1<<4, - Stmt_CheckScopeDecls = 1<<5, + Stmt_CheckScopeDecls = 1<<5, }; enum BuiltinProcPkg { @@ -316,6 +316,7 @@ struct CheckerContext { bool no_polymorphic_errors; bool hide_polymorphic_errors; bool in_polymorphic_specialization; + bool allow_arrow_right_selector_expr; Scope * polymorphic_scope; Ast *assignment_lhs_hint; diff --git a/src/main.cpp b/src/main.cpp index 97fecb094..67dc5da00 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1876,9 +1876,6 @@ int main(int arg_count, char const **arg_ptr) { SIZE_T virtual_mem_used_by_me = pmc.PrivateUsage; gb_printf_err("virtual_memory_used: %tu B\n", virtual_mem_used_by_me); - gb_printf_err("total_allocated_node_memory: %lld B\n", total_allocated_node_memory.value); - gb_printf_err("total_subtype_node_memory_test: %lld B\n", total_subtype_node_memory_test.value); - gb_printf_err("fraction: %.6f\n", (f64)total_subtype_node_memory_test.value/(f64)total_allocated_node_memory.value); Parser *p = checker.parser; isize lines = p->total_line_count; isize tokens = p->total_token_count; diff --git a/src/parser.cpp b/src/parser.cpp index 5e04aea17..476504d52 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -109,9 +109,6 @@ Token ast_token(Ast *node) { } -gb_global gbAtomic64 total_allocated_node_memory = {0}; -gb_global gbAtomic64 total_subtype_node_memory_test = {0}; - isize ast_node_size(AstKind kind) { return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *)); @@ -122,10 +119,6 @@ Ast *alloc_ast_node(AstFile *f, AstKind kind) { isize size = ast_node_size(kind); - gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast))); - gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind])); - - // Ast *node = gb_alloc_item(a, Ast); Ast *node = cast(Ast *)gb_alloc(a, size); node->kind = kind; node->file = f; @@ -2511,7 +2504,15 @@ Ast *parse_call_expr(AstFile *f, Ast *operand) { f->expr_level--; close_paren = expect_closing(f, Token_CloseParen, str_lit("argument list")); - return ast_call_expr(f, operand, args, open_paren, close_paren, ellipsis); + + Ast *call = ast_call_expr(f, operand, args, open_paren, close_paren, ellipsis); + + Ast *o = unparen_expr(operand); + if (o->kind == Ast_SelectorExpr && o->SelectorExpr.token.kind == Token_ArrowRight) { + return ast_selector_call_expr(f, o->SelectorExpr.token, o, call); + } + + return call; } Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { @@ -2563,11 +2564,10 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { case Token_ArrowRight: { Token token = advance_token(f); - // syntax_error(token, "Selector expressions use '.' rather than '->'"); - Ast *sel = ast_selector_expr(f, token, operand, parse_ident(f)); - Ast *call = parse_call_expr(f, sel); - operand = ast_selector_call_expr(f, token, sel, call); + operand = ast_selector_expr(f, token, operand, parse_ident(f)); + // Ast *call = parse_call_expr(f, sel); + // operand = ast_selector_call_expr(f, token, sel, call); break; } -- cgit v1.2.3 From 6f71d1f2a97887d7039c4e4cc39477a1f474ccae Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 12:10:25 +0000 Subject: Add `-show-unused` (Shows unused package declarations of all imported packages) Crude output at the moment but better than nothing --- src/build_settings.cpp | 1 + src/check_decl.cpp | 3 +- src/checker.cpp | 28 +++------ src/checker.hpp | 13 ++-- src/main.cpp | 159 +++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.cpp | 6 +- src/ptr_set.cpp | 29 ++++++++- 7 files changed, 207 insertions(+), 32 deletions(-) (limited to 'src/main.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 4f06c2913..5c1babe0c 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -143,6 +143,7 @@ struct BuildContext { bool generate_docs; i32 optimization_level; bool show_timings; + bool show_unused; bool show_more_timings; bool show_system_calls; bool keep_temp_files; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index da07fe4bc..5234955fb 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1007,11 +1007,10 @@ void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d) continue; } - if (ptr_set_exists(&entity_set, e)) { + if (ptr_set_update(&entity_set, e)) { error(arg, "Previous use of `%.*s` in procedure group", LIT(e->token.string)); continue; } - ptr_set_add(&entity_set, e); array_add(&pge->entities, e); } diff --git a/src/checker.cpp b/src/checker.cpp index f02b927c3..f8018506c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -700,7 +700,7 @@ void init_universal(void) { builtin_pkg->kind = Package_Normal; builtin_pkg->scope = create_scope(nullptr); - builtin_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; + builtin_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global | ScopeFlag_Builtin; builtin_pkg->scope->pkg = builtin_pkg; intrinsics_pkg = gb_alloc_item(a, AstPackage); @@ -708,7 +708,7 @@ void init_universal(void) { intrinsics_pkg->kind = Package_Normal; intrinsics_pkg->scope = create_scope(nullptr); - intrinsics_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; + intrinsics_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global | ScopeFlag_Builtin; intrinsics_pkg->scope->pkg = intrinsics_pkg; config_pkg = gb_alloc_item(a, AstPackage); @@ -716,7 +716,7 @@ void init_universal(void) { config_pkg->kind = Package_Normal; config_pkg->scope = create_scope(nullptr); - config_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global; + config_pkg->scope->flags |= ScopeFlag_Pkg | ScopeFlag_Global | ScopeFlag_Builtin; config_pkg->scope->pkg = config_pkg; @@ -1501,11 +1501,10 @@ void add_min_dep_type_info(Checker *c, Type *t) { ti_index = type_info_index(&c->info, t, false); } GB_ASSERT(ti_index >= 0); - if (ptr_set_exists(set, ti_index)) { + if (ptr_set_update(set, ti_index)) { // Type Already exists return; } - ptr_set_add(set, ti_index); // Add nested types if (t->kind == Type_Named) { @@ -1688,12 +1687,10 @@ void add_dependency_to_set(Checker *c, Entity *entity) { } } - if (ptr_set_exists(set, entity)) { + if (ptr_set_update(set, entity)) { return; } - - ptr_set_add(set, entity); DeclInfo *decl = decl_info_of_entity(entity); if (decl == nullptr) { return; @@ -3567,11 +3564,9 @@ struct ImportPathItem { Array find_import_path(Checker *c, AstPackage *start, AstPackage *end, PtrSet *visited) { Array empty_path = {}; - if (ptr_set_exists(visited, start)) { + if (ptr_set_update(visited, start)) { return empty_path; } - ptr_set_add(visited, start); - String path = start->fullpath; AstPackage **found = string_map_get(&c->info.packages, path); @@ -3657,10 +3652,8 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { GB_ASSERT(scope->flags&ScopeFlag_Pkg); - if (ptr_set_exists(&parent_scope->imported, scope)) { + if (ptr_set_update(&parent_scope->imported, scope)) { // error(token, "Multiple import of the same file within this scope"); - } else { - ptr_set_add(&parent_scope->imported, scope); } String import_name = path_to_entity_name(id->import_name.string, id->fullpath, false); @@ -4013,10 +4006,9 @@ void check_import_entities(Checker *c) { if (pkg == nullptr) { continue; } - if (ptr_set_exists(&emitted, pkg)) { + if (ptr_set_update(&emitted, pkg)) { continue; } - ptr_set_add(&emitted, pkg); array_add(&package_order, n); } @@ -4259,11 +4251,9 @@ void calculate_global_init_order(Checker *c) { // if (!decl_info_has_init(d)) { // continue; // } - if (ptr_set_exists(&emitted, d)) { + if (ptr_set_update(&emitted, d)) { continue; } - ptr_set_add(&emitted, d); - array_add(&info->variable_init_order, d); } diff --git a/src/checker.hpp b/src/checker.hpp index 9c9b77ac3..e672a477b 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -160,12 +160,13 @@ struct ProcInfo { enum ScopeFlag : i32 { - ScopeFlag_Pkg = 1<<1, - ScopeFlag_Global = 1<<2, - ScopeFlag_File = 1<<3, - ScopeFlag_Init = 1<<4, - ScopeFlag_Proc = 1<<5, - ScopeFlag_Type = 1<<6, + ScopeFlag_Pkg = 1<<1, + ScopeFlag_Builtin = 1<<2, + ScopeFlag_Global = 1<<3, + ScopeFlag_File = 1<<4, + ScopeFlag_Init = 1<<5, + ScopeFlag_Proc = 1<<6, + ScopeFlag_Type = 1<<7, ScopeFlag_HasBeenImported = 1<<10, // This is only applicable to file scopes diff --git a/src/main.cpp b/src/main.cpp index 67dc5da00..17477384e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -568,6 +568,7 @@ enum BuildFlagKind { BuildFlag_OutFile, BuildFlag_OptimizationLevel, BuildFlag_ShowTimings, + BuildFlag_ShowUnused, BuildFlag_ShowMoreTimings, BuildFlag_ShowSystemCalls, BuildFlag_ThreadCount, @@ -669,6 +670,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String); add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer); add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer); @@ -860,6 +862,14 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_timings = true; break; + case BuildFlag_ShowUnused: + GB_ASSERT(value.kind == ExactValue_Invalid); + build_context.show_unused = true; + if (build_context.command != "check") { + gb_printf_err("%.*s is only allowed with 'odin check'\n", LIT(name)); + bad_flags = true; + } + break; case BuildFlag_ShowMoreTimings: GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_timings = true; @@ -1487,6 +1497,7 @@ void print_show_help(String const arg0, String const &command) { bool build = command == "build"; bool run_or_build = command == "run" || command == "build"; + bool check_only = command == "check"; bool check = command == "run" || command == "build" || command == "check"; print_usage_line(0, ""); @@ -1521,6 +1532,12 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(0, ""); } + if (check_only) { + print_usage_line(1, "-show-unused"); + print_usage_line(2, "Shows unused package declarations within the current project"); + print_usage_line(0, ""); + } + if (run_or_build) { print_usage_line(1, "-keep-temp-files"); print_usage_line(2, "Keeps the temporary files generated during compilation"); @@ -1599,6 +1616,23 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-extra-linker-flags:"); print_usage_line(2, "Adds extra linker specific flags in a string"); print_usage_line(0, ""); + + print_usage_line(1, "-microarch:"); + print_usage_line(2, "Specifies the specific micro-architecture for the build in a string"); + print_usage_line(2, "Examples:"); + print_usage_line(3, "-microarch:sandybridge"); + print_usage_line(3, "-microarch:native"); + print_usage_line(0, ""); + } + + if (check) { + print_usage_line(1, "-disallow-do"); + print_usage_line(2, "Disallows the 'do' keyword in the project"); + print_usage_line(0, ""); + + print_usage_line(1, "-default-to-nil-allocator"); + print_usage_line(2, "Sets the default allocator to be the nil_allocator, an allocator which does nothing"); + print_usage_line(0, ""); } if (run_or_build) { @@ -1632,6 +1666,127 @@ void print_show_help(String const arg0, String const &command) { } } +int unused_entity_kind_ordering[Entity_Count] = { + /*Invalid*/ -1, + /*Constant*/ 0, + /*Variable*/ 1, + /*TypeName*/ 4, + /*Procedure*/ 2, + /*ProcGroup*/ 3, + /*Builtin*/ -1, + /*ImportName*/ -1, + /*LibraryName*/ -1, + /*Nil*/ -1, + /*Label*/ -1, +}; +char const *unused_entity_names[Entity_Count] = { + /*Invalid*/ "", + /*Constant*/ "constants", + /*Variable*/ "variables", + /*TypeName*/ "types", + /*Procedure*/ "procedures", + /*ProcGroup*/ "proc_group", + /*Builtin*/ "", + /*ImportName*/ "import names", + /*LibraryName*/ "library names", + /*Nil*/ "", + /*Label*/ "", +}; + + +GB_COMPARE_PROC(cmp_entities_for_unused) { + GB_ASSERT(a != nullptr); + GB_ASSERT(b != nullptr); + Entity *x = *cast(Entity **)a; + Entity *y = *cast(Entity **)b; + int res = 0; + res = string_compare(x->pkg->name, y->pkg->name); + if (res != 0) { + return res; + } + int ox = unused_entity_kind_ordering[x->kind]; + int oy = unused_entity_kind_ordering[y->kind]; + if (ox < oy) { + return -1; + } else if (ox > oy) { + return +1; + } + res = string_compare(x->token.string, y->token.string); + return res; +} + + +void print_show_unused(Checker *c) { + CheckerInfo *info = &c->info; + + auto unused = array_make(permanent_allocator(), 0, info->entities.count); + for_array(i, info->entities) { + Entity *e = info->entities[i]; + if (e == nullptr) { + continue; + } + if (e->pkg == nullptr || e->pkg->scope == nullptr) { + continue; + } + if (e->pkg->scope->flags & ScopeFlag_Builtin) { + continue; + } + switch (e->kind) { + case Entity_Invalid: + case Entity_Builtin: + case Entity_Nil: + case Entity_Label: + continue; + case Entity_Constant: + case Entity_Variable: + case Entity_TypeName: + case Entity_Procedure: + case Entity_ProcGroup: + case Entity_ImportName: + case Entity_LibraryName: + // Fine + break; + } + if ((e->scope->flags & (ScopeFlag_Pkg|ScopeFlag_File)) == 0) { + continue; + } + if (e->token.string.len == 0) { + continue; + } + if (e->token.string == "_") { + continue; + } + if (ptr_set_exists(&info->minimum_dependency_set, e)) { + continue; + } + array_add(&unused, e); + } + + gb_sort_array(unused.data, unused.count, cmp_entities_for_unused); + + print_usage_line(0, "Unused Package Declarations"); + + AstPackage *curr_pkg = nullptr; + EntityKind curr_entity_kind = Entity_Invalid; + for_array(i, unused) { + Entity *e = unused[i]; + if (curr_pkg != e->pkg) { + curr_pkg = e->pkg; + curr_entity_kind = Entity_Invalid; + print_usage_line(0, ""); + print_usage_line(0, "package %.*s", LIT(curr_pkg->name)); + } + if (curr_entity_kind != e->kind) { + curr_entity_kind = e->kind; + print_usage_line(1, "%s", unused_entity_names[e->kind]); + } + // TokenPos pos = e->token.pos; + // print_usage_line(2, "%.*s(%td:%td) %.*s", LIT(pos.file), pos.line, pos.column, LIT(e->token.string)); + print_usage_line(2, "%.*s", LIT(e->token.string)); + } + print_usage_line(0, ""); +} + int main(int arg_count, char const **arg_ptr) { if (arg_count < 2) { usage(make_string_c(arg_ptr[0])); @@ -1821,6 +1976,10 @@ int main(int arg_count, char const **arg_ptr) { temp_allocator_free_all(&temporary_allocator_data); if (build_context.no_output_files) { + if (build_context.show_unused) { + print_show_unused(&checker); + } + if (build_context.query_data_set_settings.ok) { generate_and_print_query_data(&checker, timings); } else { diff --git a/src/parser.cpp b/src/parser.cpp index cf464f149..4470f979b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1099,7 +1099,7 @@ Ast *ast_label_decl(AstFile *f, Token token, Ast *name) { } Ast *ast_value_decl(AstFile *f, Array const &names, Ast *type, Array const &values, bool is_mutable, - CommentGroup *docs, CommentGroup *comment) { + CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ValueDecl); result->ValueDecl.names = slice_from_array(names); result->ValueDecl.type = type; @@ -1122,7 +1122,7 @@ Ast *ast_package_decl(AstFile *f, Token token, Token name, CommentGroup *docs, C } Ast *ast_import_decl(AstFile *f, Token token, bool is_using, Token relpath, Token import_name, - CommentGroup *docs, CommentGroup *comment) { + CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ImportDecl); result->ImportDecl.token = token; result->ImportDecl.is_using = is_using; @@ -1134,7 +1134,7 @@ Ast *ast_import_decl(AstFile *f, Token token, bool is_using, Token relpath, Toke } Ast *ast_foreign_import_decl(AstFile *f, Token token, Array filepaths, Token library_name, - CommentGroup *docs, CommentGroup *comment) { + CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ForeignImportDecl); result->ForeignImportDecl.token = token; result->ForeignImportDecl.filepaths = slice_from_array(filepaths); diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index e75202663..5432fa094 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -24,6 +24,7 @@ struct PtrSet { template void ptr_set_init (PtrSet *s, gbAllocator a, isize capacity = 16); template void ptr_set_destroy(PtrSet *s); template T ptr_set_add (PtrSet *s, T ptr); +template bool ptr_set_update (PtrSet *s, T ptr); // returns true if it previously existsed template bool ptr_set_exists (PtrSet *s, T ptr); template void ptr_set_remove (PtrSet *s, T ptr); template void ptr_set_clear (PtrSet *s); @@ -146,6 +147,29 @@ gb_inline bool ptr_set_exists(PtrSet *s, T ptr) { // Returns true if it already exists template T ptr_set_add(PtrSet *s, T ptr) { + PtrSetIndex index; + PtrSetFindResult fr; + if (s->hashes.count == 0) { + ptr_set_grow(s); + } + fr = ptr_set__find(s, ptr); + if (fr.entry_index == PTR_SET_SENTINEL) { + index = ptr_set__add_entry(s, ptr); + if (fr.entry_prev != PTR_SET_SENTINEL) { + s->entries.data[fr.entry_prev].next = index; + } else { + s->hashes.data[fr.hash_index] = index; + } + } + if (ptr_set__full(s)) { + ptr_set_grow(s); + } + return ptr; +} + +template +bool ptr_set_update(PtrSet *s, T ptr) { // returns true if it previously existsed + bool exists = false; PtrSetIndex index; PtrSetFindResult fr; if (s->hashes.count == 0) { @@ -153,7 +177,7 @@ T ptr_set_add(PtrSet *s, T ptr) { } fr = ptr_set__find(s, ptr); if (fr.entry_index != PTR_SET_SENTINEL) { - index = fr.entry_index; + exists = true; } else { index = ptr_set__add_entry(s, ptr); if (fr.entry_prev != PTR_SET_SENTINEL) { @@ -165,10 +189,11 @@ T ptr_set_add(PtrSet *s, T ptr) { if (ptr_set__full(s)) { ptr_set_grow(s); } - return ptr; + return exists; } + template void ptr_set__erase(PtrSet *s, PtrSetFindResult fr) { PtrSetFindResult last; -- cgit v1.2.3 From edd9d5e50b8c976c32f7227e0dfef8ddb9443c40 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 13:02:10 +0000 Subject: Add `-show-unused-with-location` --- src/build_settings.cpp | 1 + src/docs.cpp | 125 +++++++++++++++++++++---------------------------- src/main.cpp | 98 ++++++++++++++------------------------ 3 files changed, 89 insertions(+), 135 deletions(-) (limited to 'src/main.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 5c1babe0c..3210c914c 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -144,6 +144,7 @@ struct BuildContext { i32 optimization_level; bool show_timings; bool show_unused; + bool show_unused_with_location; bool show_more_timings; bool show_system_calls; bool keep_temp_files; diff --git a/src/docs.cpp b/src/docs.cpp index 3bc0da649..a4a980e68 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -1,6 +1,58 @@ // Generates Documentation + +gb_global int print_entity_kind_ordering[Entity_Count] = { + /*Invalid*/ -1, + /*Constant*/ 0, + /*Variable*/ 1, + /*TypeName*/ 4, + /*Procedure*/ 2, + /*ProcGroup*/ 3, + /*Builtin*/ -1, + /*ImportName*/ -1, + /*LibraryName*/ -1, + /*Nil*/ -1, + /*Label*/ -1, +}; +gb_global char const *print_entity_names[Entity_Count] = { + /*Invalid*/ "", + /*Constant*/ "constants", + /*Variable*/ "variables", + /*TypeName*/ "types", + /*Procedure*/ "procedures", + /*ProcGroup*/ "proc_group", + /*Builtin*/ "", + /*ImportName*/ "import names", + /*LibraryName*/ "library names", + /*Nil*/ "", + /*Label*/ "", +}; + + +GB_COMPARE_PROC(cmp_entities_for_printing) { + GB_ASSERT(a != nullptr); + GB_ASSERT(b != nullptr); + Entity *x = *cast(Entity **)a; + Entity *y = *cast(Entity **)b; + int res = 0; + res = string_compare(x->pkg->name, y->pkg->name); + if (res != 0) { + return res; + } + int ox = print_entity_kind_ordering[x->kind]; + int oy = print_entity_kind_ordering[y->kind]; + if (ox < oy) { + return -1; + } else if (ox > oy) { + return +1; + } + res = string_compare(x->token.string, y->token.string); + return res; +} + + gbString expr_to_string(Ast *expression); +gbString type_to_string(Type *type); String alloc_comment_group_string(gbAllocator a, CommentGroup g) { isize len = 0; @@ -32,76 +84,7 @@ String alloc_comment_group_string(gbAllocator a, CommentGroup g) { return make_string(text, len); } -#if 0 -void print_type_spec(Ast *spec) { - ast_node(ts, TypeSpec, spec); - GB_ASSERT(ts->name->kind == Ast_Ident); - String name = ts->name->Ident.string; - if (name.len == 0) { - return; - } - if (name[0] == '_') { - return; - } - gb_printf("type %.*s\n", LIT(name)); -} - -void print_proc_decl(AstProcDecl *pd) { - GB_ASSERT(pd->name->kind == Ast_Ident); - String name = pd->name->Ident.string; - if (name.len == 0) { - return; - } - if (name[0] == '_') { - return; - } - - String docs = alloc_comment_group_string(heap_allocator(), pd->docs); - defer (gb_free(heap_allocator(), docs.text)); - - if (docs.len > 0) { - gb_file_write(&gb__std_files[gbFileStandard_Output], docs.text, docs.len); - } else { - return; - } - - ast_node(proc_type, ProcType, pd->type); - - gbString params = expr_to_string(proc_type->params); - defer (gb_string_free(params)); - gb_printf("proc %.*s(%s)", LIT(name), params); - if (proc_type->results != nullptr) { - ast_node(fl, FieldList, proc_type->results); - isize count = fl->list.count; - if (count > 0) { - gbString results = expr_to_string(proc_type->results); - defer (gb_string_free(results)); - gb_printf(" -> "); - if (count != 1) { - gb_printf("("); - } - gb_printf("%s", results); - if (count != 1) { - gb_printf(")"); - } - } - } - gb_printf("\n\n"); -} -#endif -void print_declaration(Ast *decl) { -} - -void generate_documentation(Parser *parser) { - // for_array(file_index, parser->files) { - // AstFile *file = parser->files[file_index]; - // Tokenizer *tokenizer = &file->tokenizer; - // String fullpath = tokenizer->fullpath; - // gb_printf("%.*s\n", LIT(fullpath)); +void generate_documentation(Checker *c) { + CheckerInfo *info = &c->info; - // for_array(decl_index, file->decls) { - // Ast *decl = file->decls[decl_index]; - // print_declaration(decl); - // } - // } } diff --git a/src/main.cpp b/src/main.cpp index 17477384e..0f27d5079 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,8 +18,8 @@ gb_global Timings global_timings = {0}; #include "checker.hpp" #include "parser.cpp" -#include "docs.cpp" #include "checker.cpp" +#include "docs.cpp" #if defined(LLVM_BACKEND_SUPPORT) @@ -522,7 +522,7 @@ void usage(String argv0) { print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable."); print_usage_line(1, "check parse and type check .odin file"); print_usage_line(1, "query parse, type check, and output a .json file containing information about the program"); - print_usage_line(1, "docs generate documentation for a .odin file"); + print_usage_line(1, "doc generate documentation .odin file, or directory of .odin files"); print_usage_line(1, "version print version"); print_usage_line(0, ""); print_usage_line(0, "For more information of flags, apply the flag to see what is possible"); @@ -569,6 +569,7 @@ enum BuildFlagKind { BuildFlag_OptimizationLevel, BuildFlag_ShowTimings, BuildFlag_ShowUnused, + BuildFlag_ShowUnusedWithLocation, BuildFlag_ShowMoreTimings, BuildFlag_ShowSystemCalls, BuildFlag_ThreadCount, @@ -671,6 +672,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer); add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer); @@ -870,6 +872,15 @@ bool parse_build_flags(Array args) { bad_flags = true; } break; + case BuildFlag_ShowUnusedWithLocation: + GB_ASSERT(value.kind == ExactValue_Invalid); + build_context.show_unused = true; + build_context.show_unused_with_location = true; + if (build_context.command != "check") { + gb_printf_err("%.*s is only allowed with 'odin check'\n", LIT(name)); + bad_flags = true; + } + break; case BuildFlag_ShowMoreTimings: GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_timings = true; @@ -1489,12 +1500,13 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "check parse and type check .odin file"); } else if (command == "query") { print_usage_line(1, "query [experimental] parse, type check, and output a .json file containing information about the program"); - } else if (command == "docs") { - print_usage_line(1, "docs generate documentation for a .odin file"); + } else if (command == "doc") { + print_usage_line(1, "doc generate documentation from a .odin file, or directory of .odin files"); } else if (command == "version") { print_usage_line(1, "version print version"); } + bool doc = command == "doc"; bool build = command == "build"; bool run_or_build = command == "run" || command == "build"; bool check_only = command == "check"; @@ -1536,6 +1548,9 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-show-unused"); print_usage_line(2, "Shows unused package declarations within the current project"); print_usage_line(0, ""); + print_usage_line(1, "-show-unused-with-location"); + print_usage_line(2, "Shows unused package declarations within the current project with the declarations source location"); + print_usage_line(0, ""); } if (run_or_build) { @@ -1666,56 +1681,6 @@ void print_show_help(String const arg0, String const &command) { } } -int unused_entity_kind_ordering[Entity_Count] = { - /*Invalid*/ -1, - /*Constant*/ 0, - /*Variable*/ 1, - /*TypeName*/ 4, - /*Procedure*/ 2, - /*ProcGroup*/ 3, - /*Builtin*/ -1, - /*ImportName*/ -1, - /*LibraryName*/ -1, - /*Nil*/ -1, - /*Label*/ -1, -}; -char const *unused_entity_names[Entity_Count] = { - /*Invalid*/ "", - /*Constant*/ "constants", - /*Variable*/ "variables", - /*TypeName*/ "types", - /*Procedure*/ "procedures", - /*ProcGroup*/ "proc_group", - /*Builtin*/ "", - /*ImportName*/ "import names", - /*LibraryName*/ "library names", - /*Nil*/ "", - /*Label*/ "", -}; - - -GB_COMPARE_PROC(cmp_entities_for_unused) { - GB_ASSERT(a != nullptr); - GB_ASSERT(b != nullptr); - Entity *x = *cast(Entity **)a; - Entity *y = *cast(Entity **)b; - int res = 0; - res = string_compare(x->pkg->name, y->pkg->name); - if (res != 0) { - return res; - } - int ox = unused_entity_kind_ordering[x->kind]; - int oy = unused_entity_kind_ordering[y->kind]; - if (ox < oy) { - return -1; - } else if (ox > oy) { - return +1; - } - res = string_compare(x->token.string, y->token.string); - return res; -} - - void print_show_unused(Checker *c) { CheckerInfo *info = &c->info; @@ -1762,7 +1727,7 @@ void print_show_unused(Checker *c) { array_add(&unused, e); } - gb_sort_array(unused.data, unused.count, cmp_entities_for_unused); + gb_sort_array(unused.data, unused.count, cmp_entities_for_printing); print_usage_line(0, "Unused Package Declarations"); @@ -1778,11 +1743,14 @@ void print_show_unused(Checker *c) { } if (curr_entity_kind != e->kind) { curr_entity_kind = e->kind; - print_usage_line(1, "%s", unused_entity_names[e->kind]); + print_usage_line(1, "%s", print_entity_names[e->kind]); + } + if (build_context.show_unused_with_location) { + TokenPos pos = e->token.pos; + print_usage_line(2, "%.*s(%td:%td) %.*s", LIT(pos.file), pos.line, pos.column, LIT(e->token.string)); + } else { + print_usage_line(2, "%.*s", LIT(e->token.string)); } - // TokenPos pos = e->token.pos; - // print_usage_line(2, "%.*s(%td:%td) %.*s", LIT(pos.file), pos.line, pos.column, LIT(e->token.string)); - print_usage_line(2, "%.*s", LIT(e->token.string)); } print_usage_line(0, ""); } @@ -1867,7 +1835,7 @@ int main(int arg_count, char const **arg_ptr) { build_context.no_output_files = true; build_context.query_data_set_settings.ok = true; init_filename = args[2]; - } else if (command == "docs") { + } else if (command == "doc") { if (args.count < 3) { usage(args[0]); return 1; @@ -1875,6 +1843,7 @@ int main(int arg_count, char const **arg_ptr) { init_filename = args[2]; build_context.generate_docs = true; + build_context.no_entry_point = true; // ignore entry point #if 1 print_usage_line(0, "Documentation generation is not yet supported"); return 1; @@ -1956,10 +1925,6 @@ int main(int arg_count, char const **arg_ptr) { temp_allocator_free_all(&temporary_allocator_data); - if (build_context.generate_docs) { - // generate_documentation(&parser); - return 0; - } timings_start_section(timings, str_lit("type check")); Checker checker = {0}; @@ -1975,6 +1940,11 @@ int main(int arg_count, char const **arg_ptr) { temp_allocator_free_all(&temporary_allocator_data); + if (build_context.generate_docs) { + generate_documentation(&checker); + return global_error_collector.count ? 1 : 0; + } + if (build_context.no_output_files) { if (build_context.show_unused) { print_show_unused(&checker); -- cgit v1.2.3 From 00192bb349993dbdd02d13f31b51809bba4d875e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 13:55:08 +0000 Subject: Improve flag handling to check for invalid uses --- src/build_settings.cpp | 32 ++++++++++++ src/docs.cpp | 40 +++++++++++++++ src/main.cpp | 133 ++++++++++++++++++++++++++++--------------------- 3 files changed, 149 insertions(+), 56 deletions(-) (limited to 'src/main.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 3210c914c..8cd516505 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -104,6 +104,35 @@ enum BuildModeKind { BuildMode_Assembly, }; +enum CommandKind : u32 { + Command_run = 1<<0, + Command_build = 1<<1, + Command_check = 1<<3, + Command_query = 1<<4, + Command_doc = 1<<5, + Command_version = 1<<6, + + Command__does_check = Command_run|Command_build|Command_check|Command_query|Command_doc, + Command__does_build = Command_run|Command_build, + Command_all = ~(u32)0, +}; + +char const *odin_command_strings[32] = { + "run", + "build", + "check", + "query", + "doc", + "version", +}; + + + +enum CmdDocFlag : u32 { + CmdDocFlag_All = 1<<0, +}; + + // This stores the information for the specify architecture of this build struct BuildContext { @@ -124,6 +153,7 @@ struct BuildContext { i64 word_size; // Size of a pointer, must be >= 4 i64 max_align; // max alignment, must be >= 1 (and typically >= word_size) + CommandKind command_kind; String command; TargetMetrics metrics; @@ -167,6 +197,8 @@ struct BuildContext { bool ignore_microsoft_magic; bool linker_map_file; + u32 cmd_doc_flags; + QueryDataSetSettings query_data_set_settings; gbAffinity affinity; diff --git a/src/docs.cpp b/src/docs.cpp index a4a980e68..237323af3 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -50,6 +50,14 @@ GB_COMPARE_PROC(cmp_entities_for_printing) { return res; } +GB_COMPARE_PROC(cmp_ast_package_by_name) { + GB_ASSERT(a != nullptr); + GB_ASSERT(b != nullptr); + AstPackage *x = *cast(AstPackage **)a; + AstPackage *y = *cast(AstPackage **)b; + return string_compare(x->name, y->name); +} + gbString expr_to_string(Ast *expression); gbString type_to_string(Type *type); @@ -84,7 +92,39 @@ String alloc_comment_group_string(gbAllocator a, CommentGroup g) { return make_string(text, len); } + +void print_doc_line(i32 indent, char const *fmt, ...) { + while (indent --> 0) { + gb_printf("\t"); + } + va_list va; + va_start(va, fmt); + gb_printf_va(fmt, va); + va_end(va); + gb_printf("\n"); +} + +void print_doc_package(CheckerInfo *info, AstPackage *pkg) { + print_doc_line(0, "%.*s", LIT(pkg->name)); +} + void generate_documentation(Checker *c) { CheckerInfo *info = &c->info; + if (build_context.cmd_doc_flags & CmdDocFlag_All) { + auto pkgs = array_make(permanent_allocator(), info->packages.entries.count); + for_array(i, info->packages.entries) { + array_add(&pkgs, info->packages.entries[i].value); + } + + gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); + + for_array(i, pkgs) { + print_doc_package(info, pkgs[i]); + } + } else { + GB_ASSERT(info->init_scope->flags & ScopeFlag_Pkg); + AstPackage *pkg = info->init_scope->pkg; + print_doc_package(info, pkg); + } } diff --git a/src/main.cpp b/src/main.cpp index 0f27d5079..45fb9ac85 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -623,10 +623,13 @@ struct BuildFlag { BuildFlagKind kind; String name; BuildFlagParamKind param_kind; + u32 command_support; + bool allow_mulitple; }; -void add_flag(Array *build_flags, BuildFlagKind kind, String name, BuildFlagParamKind param_kind) { - BuildFlag flag = {kind, name, param_kind}; + +void add_flag(Array *build_flags, BuildFlagKind kind, String name, BuildFlagParamKind param_kind, u32 command_support, bool allow_mulitple=false) { + BuildFlag flag = {kind, name, param_kind, command_support, allow_mulitple}; array_add(build_flags, flag); } @@ -667,46 +670,46 @@ ExactValue build_param_to_exact_value(String name, String param) { bool parse_build_flags(Array args) { auto build_flags = array_make(heap_allocator(), 0, BuildFlag_COUNT); - add_flag(&build_flags, BuildFlag_Help, str_lit("help"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer); - add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer); - add_flag(&build_flags, BuildFlag_KeepTempFiles, str_lit("keep-temp-files"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String); - - add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None); - - add_flag(&build_flags, BuildFlag_Compact, str_lit("compact"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_Help, str_lit("help"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer, Command__does_build); + add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None, Command_check); + add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None, Command_check); + add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer, Command_all); + add_flag(&build_flags, BuildFlag_KeepTempFiles, str_lit("keep-temp-files"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String, Command__does_check); + add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String, Command__does_check, true); + add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String, Command__does_build); // Commands_build is not used to allow for a better error message + add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None, Command__does_build); + 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_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build); + + 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_Compact, str_lit("compact"), BuildFlagParam_None, Command_query); + add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); + add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); #if defined(GB_SYSTEM_WINDOWS) - add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None); - add_flag(&build_flags, BuildFlag_ResourceFile, str_lit("resource"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_WindowsPdbName, str_lit("pdb-name"), BuildFlagParam_String); - add_flag(&build_flags, BuildFlag_Subsystem, str_lit("subsystem"), BuildFlagParam_String); + 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); + add_flag(&build_flags, BuildFlag_WindowsPdbName, str_lit("pdb-name"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_Subsystem, str_lit("subsystem"), BuildFlagParam_String, Command__does_build); #endif GB_ASSERT(args.count >= 3); @@ -736,11 +739,19 @@ bool parse_build_flags(Array args) { String param = {}; if (end < flag.len-1) param = substring(flag, 2+end, flag.len); + bool is_supported = true; bool found = false; + BuildFlag found_bf = {}; for_array(build_flag_index, build_flags) { BuildFlag bf = build_flags[build_flag_index]; if (bf.name == name) { found = true; + found_bf = bf; + if ((bf.command_support & build_context.command_kind) == 0) { + is_supported = false; + break; + } + if (set_flags[bf.kind]) { gb_printf_err("Previous flag set: '%.*s'\n", LIT(name)); bad_flags = true; @@ -867,19 +878,11 @@ bool parse_build_flags(Array args) { case BuildFlag_ShowUnused: GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_unused = true; - if (build_context.command != "check") { - gb_printf_err("%.*s is only allowed with 'odin check'\n", LIT(name)); - bad_flags = true; - } break; case BuildFlag_ShowUnusedWithLocation: GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_unused = true; build_context.show_unused_with_location = true; - if (build_context.command != "check") { - gb_printf_err("%.*s is only allowed with 'odin check'\n", LIT(name)); - bad_flags = true; - } break; case BuildFlag_ShowMoreTimings: GB_ASSERT(value.kind == ExactValue_Invalid); @@ -1252,20 +1255,30 @@ bool parse_build_flags(Array args) { } } - - switch (bf.kind) { - case BuildFlag_Define: - // Allow for multiple - break; - default: + if (!bf.allow_mulitple) { set_flags[bf.kind] = ok; - break; } } break; } } - if (!found) { + if (found && !is_supported) { + gb_printf_err("Unknown flag for 'odin %.*s': '%.*s'\n", LIT(build_context.command), LIT(name)); + gb_printf_err("'%.*s' is supported with the following commands:\n", LIT(name)); + gb_printf_err("\t"); + i32 count = 0; + for (u32 i = 0; i < 32; i++) { + if (found_bf.command_support & (1< 0) { + gb_printf_err(", "); + } + gb_printf_err("%s", odin_command_strings[i]); + count += 1; + } + } + gb_printf_err("\n"); + bad_flags = true; + } else if (!found) { gb_printf_err("Unknown flag: '%.*s'\n", LIT(name)); bad_flags = true; } @@ -1795,6 +1808,7 @@ int main(int arg_count, char const **arg_ptr) { usage(args[0]); return 1; } + build_context.command_kind = Command_run; Array run_args = array_make(heap_allocator(), 0, arg_count); defer (array_free(&run_args)); @@ -1814,17 +1828,20 @@ int main(int arg_count, char const **arg_ptr) { run_args_string = string_join_and_quote(heap_allocator(), run_args); init_filename = args[2]; run_output = true; + } else if (command == "build") { if (args.count < 3) { usage(args[0]); return 1; } + build_context.command_kind = Command_build; init_filename = args[2]; } else if (command == "check") { if (args.count < 3) { usage(args[0]); return 1; } + build_context.command_kind = Command_check; build_context.no_output_files = true; init_filename = args[2]; } else if (command == "query") { @@ -1832,6 +1849,7 @@ int main(int arg_count, char const **arg_ptr) { usage(args[0]); return 1; } + build_context.command_kind = Command_query; build_context.no_output_files = true; build_context.query_data_set_settings.ok = true; init_filename = args[2]; @@ -1841,14 +1859,17 @@ int main(int arg_count, char const **arg_ptr) { return 1; } + build_context.command_kind = Command_doc; init_filename = args[2]; + build_context.no_output_files = true; build_context.generate_docs = true; build_context.no_entry_point = true; // ignore entry point - #if 1 + #if 0 print_usage_line(0, "Documentation generation is not yet supported"); return 1; #endif } else if (command == "version") { + build_context.command_kind = Command_version; gb_printf("%.*s version %.*s", LIT(args[0]), LIT(ODIN_VERSION)); #ifdef NIGHTLY -- cgit v1.2.3 From d90fc18bef8300da0fc6102d57b9e970bd7fe935 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 15:05:16 +0000 Subject: Basic `odin doc` support --- src/build_settings.cpp | 2 + src/check_expr.cpp | 208 +++++++++++++++++++++++++++++------------------- src/checker.cpp | 4 +- src/checker.hpp | 1 + src/docs.cpp | 212 +++++++++++++++++++++++++++++++++++++++++++++++-- src/exact_value.cpp | 6 +- src/main.cpp | 23 ++++++ src/parser.cpp | 6 +- 8 files changed, 363 insertions(+), 99 deletions(-) (limited to 'src/main.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 8cd516505..0e8f2c5bc 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -130,6 +130,7 @@ char const *odin_command_strings[32] = { enum CmdDocFlag : u32 { CmdDocFlag_All = 1<<0, + CmdDocFlag_AllPackages = 1<<1, }; @@ -198,6 +199,7 @@ struct BuildContext { bool linker_map_file; u32 cmd_doc_flags; + Array doc_packages; QueryDataSetSettings query_data_set_settings; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 94a3467d2..f6530df51 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -10208,14 +10208,14 @@ void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) } -gbString write_expr_to_string(gbString str, Ast *node); +gbString write_expr_to_string(gbString str, Ast *node, bool shorthand); gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) { for_array(i, params) { if (i > 0) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, params[i]); + str = write_expr_to_string(str, params[i], false); } return str; } @@ -10229,11 +10229,23 @@ gbString string_append_string(gbString str, String string) { gbString string_append_token(gbString str, Token token) { - return string_append_string(str, token.string); + if (token.kind == Token_String) { + str = gb_string_append_rune(str, '"'); + } else if (token.kind == Token_Rune) { + str = gb_string_append_rune(str, '\''); + } + str = string_append_string(str, token.string); + if (token.kind == Token_String) { + str = gb_string_append_rune(str, '"'); + } else if (token.kind == Token_Rune) { + str = gb_string_append_rune(str, '\''); + } + + return str; } -gbString write_expr_to_string(gbString str, Ast *node) { +gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { if (node == nullptr) return str; @@ -10271,21 +10283,30 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = gb_string_appendc(str, "proc{"); for_array(i, pg->args) { if (i > 0) str = gb_string_appendc(str, ", "); - str = write_expr_to_string(str, pg->args[i]); + str = write_expr_to_string(str, pg->args[i], shorthand); } str = gb_string_append_rune(str, '}'); case_end; case_ast_node(pl, ProcLit, node); - str = write_expr_to_string(str, pl->type); + str = write_expr_to_string(str, pl->type, shorthand); + if (pl->body) { + str = gb_string_appendc(str, " {...}"); + } else { + str = gb_string_appendc(str, " ---"); + } case_end; case_ast_node(cl, CompoundLit, node); - str = write_expr_to_string(str, cl->type); + str = write_expr_to_string(str, cl->type, shorthand); str = gb_string_append_rune(str, '{'); - for_array(i, cl->elems) { - if (i > 0) str = gb_string_appendc(str, ", "); - str = write_expr_to_string(str, cl->elems[i]); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + for_array(i, cl->elems) { + if (i > 0) str = gb_string_appendc(str, ", "); + str = write_expr_to_string(str, cl->elems[i], shorthand); + } } str = gb_string_append_rune(str, '}'); case_end; @@ -10294,71 +10315,71 @@ gbString write_expr_to_string(gbString str, Ast *node) { case_ast_node(te, TagExpr, node); str = gb_string_append_rune(str, '#'); str = string_append_token(str, te->name); - str = write_expr_to_string(str, te->expr); + str = write_expr_to_string(str, te->expr, shorthand); case_end; case_ast_node(ue, UnaryExpr, node); str = string_append_token(str, ue->op); - str = write_expr_to_string(str, ue->expr); + str = write_expr_to_string(str, ue->expr, shorthand); case_end; case_ast_node(de, DerefExpr, node); - str = write_expr_to_string(str, de->expr); + str = write_expr_to_string(str, de->expr, shorthand); str = gb_string_append_rune(str, '^'); case_end; case_ast_node(be, BinaryExpr, node); - str = write_expr_to_string(str, be->left); + str = write_expr_to_string(str, be->left, shorthand); str = gb_string_append_rune(str, ' '); str = string_append_token(str, be->op); str = gb_string_append_rune(str, ' '); - str = write_expr_to_string(str, be->right); + str = write_expr_to_string(str, be->right, shorthand); case_end; case_ast_node(te, TernaryExpr, node); - str = write_expr_to_string(str, te->cond); + str = write_expr_to_string(str, te->cond, shorthand); str = gb_string_appendc(str, " ? "); - str = write_expr_to_string(str, te->x); + str = write_expr_to_string(str, te->x, shorthand); str = gb_string_appendc(str, " : "); - str = write_expr_to_string(str, te->y); + str = write_expr_to_string(str, te->y, shorthand); case_end; case_ast_node(te, TernaryIfExpr, node); - str = write_expr_to_string(str, te->x); + str = write_expr_to_string(str, te->x, shorthand); str = gb_string_appendc(str, " if "); - str = write_expr_to_string(str, te->cond); + str = write_expr_to_string(str, te->cond, shorthand); str = gb_string_appendc(str, " else "); - str = write_expr_to_string(str, te->y); + str = write_expr_to_string(str, te->y, shorthand); case_end; case_ast_node(te, TernaryWhenExpr, node); - str = write_expr_to_string(str, te->x); + str = write_expr_to_string(str, te->x, shorthand); str = gb_string_appendc(str, " when "); - str = write_expr_to_string(str, te->cond); + str = write_expr_to_string(str, te->cond, shorthand); str = gb_string_appendc(str, " else "); - str = write_expr_to_string(str, te->y); + str = write_expr_to_string(str, te->y, shorthand); case_end; case_ast_node(pe, ParenExpr, node); str = gb_string_append_rune(str, '('); - str = write_expr_to_string(str, pe->expr); + str = write_expr_to_string(str, pe->expr, shorthand); str = gb_string_append_rune(str, ')'); case_end; case_ast_node(se, SelectorExpr, node); - str = write_expr_to_string(str, se->expr); + str = write_expr_to_string(str, se->expr, shorthand); str = string_append_token(str, se->token); - str = write_expr_to_string(str, se->selector); + str = write_expr_to_string(str, se->selector, shorthand); case_end; case_ast_node(se, ImplicitSelectorExpr, node); str = gb_string_append_rune(str, '.'); - str = write_expr_to_string(str, se->selector); + str = write_expr_to_string(str, se->selector, shorthand); case_end; case_ast_node(se, SelectorCallExpr, node); - str = write_expr_to_string(str, se->expr); + str = write_expr_to_string(str, se->expr, shorthand); str = gb_string_appendc(str, "("); ast_node(ce, CallExpr, se->call); isize start = se->modified_call ? 1 : 0; @@ -10367,86 +10388,86 @@ gbString write_expr_to_string(gbString str, Ast *node) { if (i > start) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, arg); + str = write_expr_to_string(str, arg, shorthand); } str = gb_string_appendc(str, ")"); case_end; case_ast_node(ta, TypeAssertion, node); - str = write_expr_to_string(str, ta->expr); + str = write_expr_to_string(str, ta->expr, shorthand); str = gb_string_appendc(str, ".("); - str = write_expr_to_string(str, ta->type); + str = write_expr_to_string(str, ta->type, shorthand); str = gb_string_append_rune(str, ')'); case_end; case_ast_node(tc, TypeCast, node); str = string_append_token(str, tc->token); str = gb_string_append_rune(str, '('); - str = write_expr_to_string(str, tc->type); + str = write_expr_to_string(str, tc->type, shorthand); str = gb_string_append_rune(str, ')'); - str = write_expr_to_string(str, tc->expr); + str = write_expr_to_string(str, tc->expr, shorthand); case_end; case_ast_node(ac, AutoCast, node); str = string_append_token(str, ac->token); str = gb_string_append_rune(str, ' '); - str = write_expr_to_string(str, ac->expr); + str = write_expr_to_string(str, ac->expr, shorthand); case_end; case_ast_node(ie, IndexExpr, node); - str = write_expr_to_string(str, ie->expr); + str = write_expr_to_string(str, ie->expr, shorthand); str = gb_string_append_rune(str, '['); - str = write_expr_to_string(str, ie->index); + str = write_expr_to_string(str, ie->index, shorthand); str = gb_string_append_rune(str, ']'); case_end; case_ast_node(se, SliceExpr, node); - str = write_expr_to_string(str, se->expr); + str = write_expr_to_string(str, se->expr, shorthand); str = gb_string_append_rune(str, '['); - str = write_expr_to_string(str, se->low); + str = write_expr_to_string(str, se->low, shorthand); str = string_append_token(str, se->interval); - str = write_expr_to_string(str, se->high); + str = write_expr_to_string(str, se->high, shorthand); str = gb_string_append_rune(str, ']'); case_end; case_ast_node(e, Ellipsis, node); str = gb_string_appendc(str, ".."); - str = write_expr_to_string(str, e->expr); + str = write_expr_to_string(str, e->expr, shorthand); case_end; case_ast_node(fv, FieldValue, node); - str = write_expr_to_string(str, fv->field); + str = write_expr_to_string(str, fv->field, shorthand); str = gb_string_appendc(str, " = "); - str = write_expr_to_string(str, fv->value); + str = write_expr_to_string(str, fv->value, shorthand); case_end; case_ast_node(ht, HelperType, node); str = gb_string_appendc(str, "#type "); - str = write_expr_to_string(str, ht->type); + str = write_expr_to_string(str, ht->type, shorthand); case_end; case_ast_node(ht, DistinctType, node); str = gb_string_appendc(str, "distinct "); - str = write_expr_to_string(str, ht->type); + str = write_expr_to_string(str, ht->type, shorthand); case_end; case_ast_node(ht, OpaqueType, node); str = gb_string_appendc(str, "opaque "); - str = write_expr_to_string(str, ht->type); + str = write_expr_to_string(str, ht->type, shorthand); case_end; case_ast_node(pt, PolyType, node); str = gb_string_append_rune(str, '$'); - str = write_expr_to_string(str, pt->type); + str = write_expr_to_string(str, pt->type, shorthand); if (pt->specialization != nullptr) { str = gb_string_append_rune(str, '/'); - str = write_expr_to_string(str, pt->specialization); + str = write_expr_to_string(str, pt->specialization, shorthand); } case_end; case_ast_node(pt, PointerType, node); str = gb_string_append_rune(str, '^'); - str = write_expr_to_string(str, pt->type); + str = write_expr_to_string(str, pt->type, shorthand); case_end; case_ast_node(at, ArrayType, node); @@ -10456,40 +10477,44 @@ gbString write_expr_to_string(gbString str, Ast *node) { at->count->UnaryExpr.op.kind == Token_Question) { str = gb_string_appendc(str, "?"); } else { - str = write_expr_to_string(str, at->count); + str = write_expr_to_string(str, at->count, shorthand); } str = gb_string_append_rune(str, ']'); - str = write_expr_to_string(str, at->elem); + str = write_expr_to_string(str, at->elem, shorthand); case_end; case_ast_node(at, DynamicArrayType, node); str = gb_string_appendc(str, "[dynamic]"); - str = write_expr_to_string(str, at->elem); + str = write_expr_to_string(str, at->elem, shorthand); case_end; case_ast_node(bf, BitFieldType, node); str = gb_string_appendc(str, "bit_field "); if (bf->align) { str = gb_string_appendc(str, "#align "); - str = write_expr_to_string(str, bf->align); + str = write_expr_to_string(str, bf->align, shorthand); } str = gb_string_appendc(str, "{"); - str = write_struct_fields_to_string(str, bf->fields); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + str = write_struct_fields_to_string(str, bf->fields); + } str = gb_string_appendc(str, "}"); case_end; case_ast_node(bs, BitSetType, node); str = gb_string_appendc(str, "bit_set["); - str = write_expr_to_string(str, bs->elem); + str = write_expr_to_string(str, bs->elem, shorthand); str = gb_string_appendc(str, "]"); case_end; case_ast_node(mt, MapType, node); str = gb_string_appendc(str, "map["); - str = write_expr_to_string(str, mt->key); + str = write_expr_to_string(str, mt->key, shorthand); str = gb_string_append_rune(str, ']'); - str = write_expr_to_string(str, mt->value); + str = write_expr_to_string(str, mt->value, shorthand); case_end; case_ast_node(f, Field, node); @@ -10509,7 +10534,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { for_array(i, f->names) { Ast *name = f->names[i]; if (i > 0) str = gb_string_appendc(str, ", "); - str = write_expr_to_string(str, name); + str = write_expr_to_string(str, name, shorthand); } if (f->names.count > 0) { if (f->type == nullptr && f->default_value != nullptr) { @@ -10519,14 +10544,14 @@ gbString write_expr_to_string(gbString str, Ast *node) { } if (f->type != nullptr) { str = gb_string_append_rune(str, ' '); - str = write_expr_to_string(str, f->type); + str = write_expr_to_string(str, f->type, shorthand); } if (f->default_value != nullptr) { if (f->type != nullptr) { str = gb_string_append_rune(str, ' '); } str = gb_string_appendc(str, "= "); - str = write_expr_to_string(str, f->default_value); + str = write_expr_to_string(str, f->default_value, shorthand); } case_end; @@ -10552,7 +10577,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { for_array(i, f->list) { if (i > 0) str = gb_string_appendc(str, ", "); if (has_name) { - str = write_expr_to_string(str, f->list[i]); + str = write_expr_to_string(str, f->list[i], shorthand); } else { ast_node(field, Field, f->list[i]); @@ -10566,7 +10591,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = gb_string_appendc(str, "#c_vararg "); } - str = write_expr_to_string(str, field->type); + str = write_expr_to_string(str, field->type, shorthand); } } case_end; @@ -10581,7 +10606,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { break; } - str = write_expr_to_string(str, ce->proc); + str = write_expr_to_string(str, ce->proc, shorthand); str = gb_string_appendc(str, "("); for_array(i, ce->args) { @@ -10589,7 +10614,7 @@ gbString write_expr_to_string(gbString str, Ast *node) { if (i > 0) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, arg); + str = write_expr_to_string(str, arg, shorthand); } str = gb_string_appendc(str, ")"); case_end; @@ -10598,17 +10623,17 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = gb_string_appendc(str, "typeid"); if (tt->specialization) { str = gb_string_appendc(str, "/"); - str = write_expr_to_string(str, tt->specialization); + str = write_expr_to_string(str, tt->specialization, shorthand); } case_end; case_ast_node(pt, ProcType, node); str = gb_string_appendc(str, "proc("); - str = write_expr_to_string(str, pt->params); + str = write_expr_to_string(str, pt->params, shorthand); str = gb_string_appendc(str, ")"); if (pt->results != nullptr) { str = gb_string_appendc(str, " -> "); - str = write_expr_to_string(str, pt->results); + str = write_expr_to_string(str, pt->results, shorthand); } case_end; @@ -10618,7 +10643,11 @@ gbString write_expr_to_string(gbString str, Ast *node) { if (st->is_packed) str = gb_string_appendc(str, "#packed "); if (st->is_raw_union) str = gb_string_appendc(str, "#raw_union "); str = gb_string_append_rune(str, '{'); - str = write_struct_fields_to_string(str, st->fields); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + str = write_struct_fields_to_string(str, st->fields); + } str = gb_string_append_rune(str, '}'); case_end; @@ -10626,30 +10655,38 @@ gbString write_expr_to_string(gbString str, Ast *node) { case_ast_node(st, UnionType, node); str = gb_string_appendc(str, "union "); str = gb_string_append_rune(str, '{'); - str = write_struct_fields_to_string(str, st->variants); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + str = write_struct_fields_to_string(str, st->variants); + } str = gb_string_append_rune(str, '}'); case_end; case_ast_node(et, EnumType, node); str = gb_string_appendc(str, "enum "); if (et->base_type != nullptr) { - str = write_expr_to_string(str, et->base_type); + str = write_expr_to_string(str, et->base_type, shorthand); str = gb_string_append_rune(str, ' '); } str = gb_string_append_rune(str, '{'); - for_array(i, et->fields) { - if (i > 0) { - str = gb_string_appendc(str, ", "); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + for_array(i, et->fields) { + if (i > 0) { + str = gb_string_appendc(str, ", "); + } + str = write_expr_to_string(str, et->fields[i], shorthand); } - str = write_expr_to_string(str, et->fields[i]); } str = gb_string_append_rune(str, '}'); case_end; case_ast_node(rt, RelativeType, node); - str = write_expr_to_string(str, rt->tag); + str = write_expr_to_string(str, rt->tag, shorthand); str = gb_string_appendc(str, "" ); - str = write_expr_to_string(str, rt->type); + str = write_expr_to_string(str, rt->type, shorthand); case_end; @@ -10659,12 +10696,12 @@ gbString write_expr_to_string(gbString str, Ast *node) { if (i > 0) { str = gb_string_appendc(str, ", "); } - str = write_expr_to_string(str, ia->param_types[i]); + str = write_expr_to_string(str, ia->param_types[i], shorthand); } str = gb_string_appendc(str, ")"); if (ia->return_type != nullptr) { str = gb_string_appendc(str, " -> "); - str = write_expr_to_string(str, ia->return_type); + str = write_expr_to_string(str, ia->return_type, shorthand); } if (ia->has_side_effects) { str = gb_string_appendc(str, " #side_effects"); @@ -10677,9 +10714,13 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = gb_string_appendc(str, inline_asm_dialect_strings[ia->dialect]); } str = gb_string_appendc(str, " {"); - str = write_expr_to_string(str, ia->asm_string); - str = gb_string_appendc(str, ", "); - str = write_expr_to_string(str, ia->constraints_string); + if (shorthand) { + str = gb_string_appendc(str, "..."); + } else { + str = write_expr_to_string(str, ia->asm_string, shorthand); + str = gb_string_appendc(str, ", "); + str = write_expr_to_string(str, ia->constraints_string, shorthand); + } str = gb_string_appendc(str, "}"); case_end; } @@ -10688,5 +10729,8 @@ gbString write_expr_to_string(gbString str, Ast *node) { } gbString expr_to_string(Ast *expression) { - return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression); + return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, false); +} +gbString expr_to_string_shorthand(Ast *expression) { + return write_expr_to_string(gb_string_make(heap_allocator(), ""), expression, true); } diff --git a/src/checker.cpp b/src/checker.cpp index f8018506c..8f8aa7381 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3115,6 +3115,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { Ast *init_expr = value; DeclInfo *d = make_decl_info(c->scope, c->decl); + d->decl_node = decl; d->entity = e; d->type_expr = vd->type; d->init_expr = init_expr; @@ -3142,9 +3143,10 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { Token token = name->Ident.token; Ast *fl = c->foreign_context.curr_library; - DeclInfo *d = make_decl_info(c->scope, c->decl); Entity *e = nullptr; + DeclInfo *d = make_decl_info(c->scope, c->decl); + d->decl_node = decl; d->attributes = vd->attributes; d->type_expr = vd->type; d->init_expr = init; diff --git a/src/checker.hpp b/src/checker.hpp index e672a477b..97469908b 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -132,6 +132,7 @@ struct DeclInfo { Entity *entity; + Ast * decl_node; Ast * type_expr; Ast * init_expr; Array attributes; diff --git a/src/docs.cpp b/src/docs.cpp index 237323af3..76d8c5433 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -59,9 +59,6 @@ GB_COMPARE_PROC(cmp_ast_package_by_name) { } -gbString expr_to_string(Ast *expression); -gbString type_to_string(Type *type); - String alloc_comment_group_string(gbAllocator a, CommentGroup g) { isize len = 0; for_array(i, g.list) { @@ -103,18 +100,216 @@ void print_doc_line(i32 indent, char const *fmt, ...) { va_end(va); gb_printf("\n"); } +void print_doc_line_no_newline(i32 indent, char const *fmt, ...) { + while (indent --> 0) { + gb_printf("\t"); + } + va_list va; + va_start(va, fmt); + gb_printf_va(fmt, va); + va_end(va); +} + +bool print_doc_comment_group_string(i32 indent, CommentGroup const &g) { + isize len = 0; + for_array(i, g.list) { + String comment = g.list[i].string; + len += comment.len; + len += 1; // for \n + } + if (len == 0) { + return false; + } + + isize count = 0; + for_array(i, g.list) { + String comment = g.list[i].string; + if (comment[1] == '/') { + comment.text += 2; + comment.len -= 2; + } else if (comment[1] == '*') { + comment.text += 2; + comment.len -= 4; + } + comment = string_trim_whitespace(comment); + if (string_starts_with(comment, str_lit("@("))) { + continue; + } + + print_doc_line(indent, "%.*s", LIT(comment)); + count += 1; + } + return count > 0; +} + + + + +void print_doc_expr(Ast *expr) { + gbString s = nullptr; + if (build_context.cmd_doc_flags & CmdDocFlag_All) { + s = expr_to_string(expr); + } else { + s = expr_to_string_shorthand(expr); + } + gb_file_write(gb_file_get_standard(gbFileStandard_Output), s, gb_string_length(s)); + gb_string_free(s); +} + void print_doc_package(CheckerInfo *info, AstPackage *pkg) { - print_doc_line(0, "%.*s", LIT(pkg->name)); + if (pkg == nullptr) { + return; + } + + print_doc_line(0, "package %.*s", LIT(pkg->name)); + + if (pkg->scope != nullptr) { + auto entities = array_make(heap_allocator(), 0, pkg->scope->elements.entries.count); + defer (array_free(&entities)); + for_array(i, pkg->scope->elements.entries) { + Entity *e = pkg->scope->elements.entries[i].value; + switch (e->kind) { + case Entity_Invalid: + case Entity_Builtin: + case Entity_Nil: + case Entity_Label: + continue; + case Entity_Constant: + case Entity_Variable: + case Entity_TypeName: + case Entity_Procedure: + case Entity_ProcGroup: + case Entity_ImportName: + case Entity_LibraryName: + // Fine + break; + } + array_add(&entities, e); + } + gb_sort_array(entities.data, entities.count, cmp_entities_for_printing); + + AstPackage *curr_pkg = nullptr; + EntityKind curr_entity_kind = Entity_Invalid; + for_array(i, entities) { + Entity *e = entities[i]; + if (e->pkg != pkg) { + continue; + } + if (!is_entity_exported(e)) { + continue; + } + + if (curr_entity_kind != e->kind) { + curr_entity_kind = e->kind; + print_doc_line(0, ""); + print_doc_line(1, "%s", print_entity_names[e->kind]); + } + + Ast *type_expr = nullptr; + Ast *init_expr = nullptr; + Ast *decl_node = nullptr; + if (e->decl_info != nullptr) { + type_expr = e->decl_info->type_expr; + init_expr = e->decl_info->init_expr; + decl_node = e->decl_info->decl_node; + } + GB_ASSERT(type_expr != nullptr || init_expr != nullptr); + print_doc_line_no_newline(2, "%.*s", LIT(e->token.string)); + if (type_expr != nullptr) { + gbString t = expr_to_string(type_expr); + gb_printf(": %s ", t); + gb_string_free(t); + } else { + gb_printf(" :"); + } + if (e->kind == Entity_Variable) { + if (init_expr != nullptr) { + gb_printf("= "); + print_doc_expr(init_expr); + } + } else { + gb_printf(": "); + print_doc_expr(init_expr); + } + + gb_printf(";\n"); + + + if (decl_node && (true || (build_context.cmd_doc_flags & CmdDocFlag_All))) { + CommentGroup *docs = nullptr; + CommentGroup *comment = nullptr; + switch (decl_node->kind) { + case_ast_node(vd, ValueDecl, decl_node); + docs = vd->docs; + comment = vd->comment; + case_end; + + case_ast_node(id, ImportDecl, decl_node); + docs = id->docs; + comment = id->comment; + case_end; + + case_ast_node(fl, ForeignImportDecl, decl_node); + docs = fl->docs; + comment = fl->comment; + case_end; + + case_ast_node(fb, ForeignBlockDecl, decl_node); + docs = fb->docs; + case_end; + } + if (comment) { + // gb_printf(" "); + } + if (docs) { + if (print_doc_comment_group_string(3, *docs)) { + gb_printf("\n"); + } + } + } + } + print_doc_line(0, ""); + } + + if (pkg->fullpath.len != 0) { + print_doc_line(0, ""); + print_doc_line(1, "fullpath: %.*s", LIT(pkg->fullpath)); + print_doc_line(1, "files:"); + for_array(i, pkg->files) { + AstFile *f = pkg->files[i]; + String filename = remove_directory_from_path(f->fullpath); + print_doc_line(2, "%.*s", LIT(filename)); + } + } + } void generate_documentation(Checker *c) { CheckerInfo *info = &c->info; - if (build_context.cmd_doc_flags & CmdDocFlag_All) { - auto pkgs = array_make(permanent_allocator(), info->packages.entries.count); - for_array(i, info->packages.entries) { - array_add(&pkgs, info->packages.entries[i].value); + if (build_context.doc_packages.count != 0) { + auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); + bool was_error = false; + for_array(j, build_context.doc_packages) { + bool found = false; + String name = build_context.doc_packages[j]; + for_array(i, info->packages.entries) { + AstPackage *pkg = info->packages.entries[i].value; + if (name == pkg->name) { + found = true; + array_add(&pkgs, pkg); + break; + } + } + if (!found) { + gb_printf_err("Unknown package %.*s\n", LIT(name)); + was_error = true; + } + } + if (was_error) { + gb_exit(1); + return; } gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); @@ -126,5 +321,6 @@ void generate_documentation(Checker *c) { GB_ASSERT(info->init_scope->flags & ScopeFlag_Pkg); AstPackage *pkg = info->init_scope->pkg; print_doc_package(info, pkg); + } } diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 9e22c0483..051b6d76a 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -945,7 +945,7 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) { Entity *strip_entity_wrapping(Ast *expr); Entity *strip_entity_wrapping(Entity *e); -gbString write_expr_to_string(gbString str, Ast *node); +gbString write_expr_to_string(gbString str, Ast *node, bool shorthand); gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) { switch (v.kind) { @@ -981,9 +981,9 @@ gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize st case ExactValue_Pointer: return str; case ExactValue_Compound: - return write_expr_to_string(str, v.value_compound); + return write_expr_to_string(str, v.value_compound, false); case ExactValue_Procedure: - return write_expr_to_string(str, v.value_procedure); + return write_expr_to_string(str, v.value_procedure, false); } return str; }; diff --git a/src/main.cpp b/src/main.cpp index 45fb9ac85..d6dc3f9b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -598,6 +598,8 @@ enum BuildFlagKind { BuildFlag_GlobalDefinitions, BuildFlag_GoToDefinitions, + BuildFlag_Package, + #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, BuildFlag_ResourceFile, @@ -704,6 +706,8 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); + add_flag(&build_flags, BuildFlag_Package, str_lit("package"), BuildFlagParam_String, Command_doc, true); + #if defined(GB_SYSTEM_WINDOWS) add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); @@ -1192,6 +1196,15 @@ bool parse_build_flags(Array args) { } break; + case BuildFlag_Package: + GB_ASSERT(value.kind == ExactValue_String); + if (value.value_string.len == 0) { + gb_printf_err("Invalid use of -package flag\n"); + } else { + array_add(&build_context.doc_packages, value.value_string); + } + break; + #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: GB_ASSERT(value.kind == ExactValue_Invalid); @@ -1529,6 +1542,14 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "Flags"); print_usage_line(0, ""); + if (doc) { + print_usage_line(1, "-package:"); + print_usage_line(2, "Add package name to generate documentation for"); + print_usage_line(2, "Multiple flags are allowed"); + print_usage_line(2, "Example: -doc:runtime"); + print_usage_line(0, ""); + } + if (run_or_build) { print_usage_line(1, "-out:"); print_usage_line(2, "Set the file name of the outputted executable"); @@ -1795,6 +1816,8 @@ int main(int arg_count, char const **arg_ptr) { add_library_collection(str_lit("core"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("core"))); map_init(&build_context.defined_values, heap_allocator()); + build_context.doc_packages.allocator = heap_allocator(); + Array args = setup_args(arg_count, arg_ptr); diff --git a/src/parser.cpp b/src/parser.cpp index 4470f979b..ce5e53d92 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4648,10 +4648,6 @@ void parser_add_foreign_file_to_process(Parser *p, AstPackage *pkg, AstForeignFi // NOTE(bill): Returns true if it's added bool try_add_import_path(Parser *p, String const &path, String const &rel_path, TokenPos pos, PackageKind kind = Package_Normal) { - if (build_context.generate_docs) { - return false; - } - String const FILE_EXT = str_lit(".odin"); gb_mutex_lock(&p->file_add_mutex); @@ -5253,7 +5249,7 @@ ParseFileError parse_packages(Parser *p, String init_filename) { } TokenPos init_pos = {}; - if (!build_context.generate_docs) { + { String s = get_fullpath_core(heap_allocator(), str_lit("runtime")); try_add_import_path(p, s, s, init_pos, Package_Runtime); } -- cgit v1.2.3 From a0fbc563173318821af945c76d8417cf599abdbd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 15:13:38 +0000 Subject: Improve flags for `odin doc` --- src/checker.cpp | 4 ++++ src/checker.hpp | 3 +++ src/docs.cpp | 38 +++++++++++++++----------------------- src/main.cpp | 18 +++++++++++++++++- 4 files changed, 39 insertions(+), 24 deletions(-) (limited to 'src/main.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 8f8aa7381..88aed4c62 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3116,6 +3116,8 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { Ast *init_expr = value; DeclInfo *d = make_decl_info(c->scope, c->decl); d->decl_node = decl; + d->comment = vd->comment; + d->docs = vd->docs; d->entity = e; d->type_expr = vd->type; d->init_expr = init_expr; @@ -3147,6 +3149,8 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { DeclInfo *d = make_decl_info(c->scope, c->decl); d->decl_node = decl; + d->comment = vd->comment; + d->docs = vd->docs; d->attributes = vd->attributes; d->type_expr = vd->type; d->init_expr = init; diff --git a/src/checker.hpp b/src/checker.hpp index 97469908b..b986296e0 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -141,6 +141,9 @@ struct DeclInfo { bool is_using; bool where_clauses_evaluated; + CommentGroup *comment; + CommentGroup *docs; + PtrSet deps; PtrSet type_info_deps; Array labels; diff --git a/src/docs.cpp b/src/docs.cpp index 76d8c5433..f65b07746 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -209,6 +209,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { Ast *type_expr = nullptr; Ast *init_expr = nullptr; Ast *decl_node = nullptr; + CommentGroup *comment = nullptr; + CommentGroup *docs = nullptr; if (e->decl_info != nullptr) { type_expr = e->decl_info->type_expr; init_expr = e->decl_info->init_expr; @@ -236,29 +238,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { gb_printf(";\n"); - if (decl_node && (true || (build_context.cmd_doc_flags & CmdDocFlag_All))) { - CommentGroup *docs = nullptr; - CommentGroup *comment = nullptr; - switch (decl_node->kind) { - case_ast_node(vd, ValueDecl, decl_node); - docs = vd->docs; - comment = vd->comment; - case_end; - - case_ast_node(id, ImportDecl, decl_node); - docs = id->docs; - comment = id->comment; - case_end; - - case_ast_node(fl, ForeignImportDecl, decl_node); - docs = fl->docs; - comment = fl->comment; - case_end; - - case_ast_node(fb, ForeignBlockDecl, decl_node); - docs = fb->docs; - case_end; - } + if (build_context.cmd_doc_flags & CmdDocFlag_All) { if (comment) { // gb_printf(" "); } @@ -314,6 +294,18 @@ void generate_documentation(Checker *c) { gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); + for_array(i, pkgs) { + print_doc_package(info, pkgs[i]); + } + } else if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) { + auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); + for_array(i, info->packages.entries) { + AstPackage *pkg = info->packages.entries[i].value; + array_add(&pkgs, pkg); + } + + gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); + for_array(i, pkgs) { print_doc_package(info, pkgs[i]); } diff --git a/src/main.cpp b/src/main.cpp index d6dc3f9b8..2c7736762 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -599,6 +599,8 @@ enum BuildFlagKind { BuildFlag_GoToDefinitions, BuildFlag_Package, + BuildFlag_All, + BuildFlag_AllPackages, #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, @@ -706,7 +708,9 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_Package, str_lit("package"), BuildFlagParam_String, Command_doc, true); + add_flag(&build_flags, BuildFlag_Package, str_lit("package"), BuildFlagParam_String, Command_doc, true); + add_flag(&build_flags, BuildFlag_All, str_lit("all"), BuildFlagParam_None, Command_doc); + add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); #if defined(GB_SYSTEM_WINDOWS) @@ -1204,6 +1208,13 @@ bool parse_build_flags(Array args) { array_add(&build_context.doc_packages, value.value_string); } break; + case BuildFlag_All: + build_context.cmd_doc_flags |= CmdDocFlag_All; + break; + case BuildFlag_AllPackages: + build_context.cmd_doc_flags |= CmdDocFlag_AllPackages; + break; + #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: @@ -1297,6 +1308,11 @@ bool parse_build_flags(Array args) { } } + if (build_context.doc_packages.count > 0 && set_flags[BuildFlag_AllPackages]) { + gb_printf_err("'odin doc' does not allow both flags together '-all-packages' and '-package' together");; + bad_flags = true; + } + if (build_context.query_data_set_settings.ok) { if (build_context.query_data_set_settings.kind == QueryDataSet_Invalid) { -- cgit v1.2.3 From 4f303603e764c219e56dae559d7e36358b199c31 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 15:15:26 +0000 Subject: Add more documentation for odin doc flags --- src/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 2c7736762..5faedbccb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1559,11 +1559,19 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(0, ""); if (doc) { + print_usage_line(1, "-all"); + print_usage_line(2, "Show all documentation for the packages"); + print_usage_line(0, ""); + print_usage_line(1, "-package:"); print_usage_line(2, "Add package name to generate documentation for"); print_usage_line(2, "Multiple flags are allowed"); print_usage_line(2, "Example: -doc:runtime"); print_usage_line(0, ""); + + print_usage_line(1, "-all-packages"); + print_usage_line(2, "Generates documentation for all packages used in the current project"); + print_usage_line(0, ""); } if (run_or_build) { -- cgit v1.2.3 From 2bd0fd932a4eb1c2e6bc8702450c230186bb3c44 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 18:50:30 +0000 Subject: Begin rudimentary work on implementing `odin test` tooling with `*_test.odin` files --- src/build_settings.cpp | 18 ++++++++++++++++-- src/checker.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/checker.hpp | 2 ++ src/ir.cpp | 13 ++++++++++--- src/llvm_backend.cpp | 18 ++++++++++++++---- src/main.cpp | 15 ++++++++++----- src/parser.hpp | 2 ++ 7 files changed, 102 insertions(+), 16 deletions(-) (limited to 'src/main.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 0e8f2c5bc..35dc9a7c1 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -111,9 +111,10 @@ enum CommandKind : u32 { Command_query = 1<<4, Command_doc = 1<<5, Command_version = 1<<6, + Command_test = 1<<7, - Command__does_check = Command_run|Command_build|Command_check|Command_query|Command_doc, - Command__does_build = Command_run|Command_build, + Command__does_check = Command_run|Command_build|Command_check|Command_query|Command_doc|Command_test, + Command__does_build = Command_run|Command_build|Command_test, Command_all = ~(u32)0, }; @@ -333,6 +334,19 @@ bool is_excluded_target_filename(String name) { String original_name = name; name = remove_extension_from_path(name); + if (string_starts_with(name, str_lit("."))) { + // Ignore .*.odin files + return true; + } + + String test_suffix = str_lit("_test"); + if (build_context.command_kind != Command_test) { + if (string_ends_with(name, test_suffix) && name != test_suffix) { + // Ignore *_test.odin files + return true; + } + } + String str1 = {}; String str2 = {}; isize n = 0; diff --git a/src/checker.cpp b/src/checker.cpp index 88aed4c62..61b1e4bae 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -839,6 +839,8 @@ void init_checker_info(CheckerInfo *i) { array_init(&i->variable_init_order, a); array_init(&i->required_foreign_imports_through_force, a); array_init(&i->required_global_variables, a); + array_init(&i->testing_procedures, a, 0, 0); + i->allow_identifier_uses = build_context.query_data_set_settings.kind == QueryDataSet_GoToDefinitions; if (i->allow_identifier_uses) { @@ -1854,7 +1856,50 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { } } - add_dependency_to_set(c, start); + if (build_context.command_kind == Command_test) { + AstPackage *pkg = c->info.init_package; + Scope *s = pkg->scope; + for_array(i, s->elements.entries) { + Entity *e = s->elements.entries[i].value; + if (e->kind != Entity_Procedure) { + continue; + } + String name = e->token.string; + String prefix = str_lit("test_"); + + + if (!string_starts_with(name, prefix)) { + continue; + } + + bool is_tester = false; + if (name != prefix) { + is_tester = true; + } else { + if (e->file && e->file->is_test) { + error(e->token, "Invalid testing procedure name: %.*s", LIT(name)); + } + } + + Type *t = base_type(e->type); + GB_ASSERT(t->kind == Type_Proc); + if (t->Proc.param_count == 0 && t->Proc.result_count == 0) { + // Good + } else { + gbString str = type_to_string(t); + error(e->token, "Testing procedures must have a signature type of proc(), got %s", str); + gb_string_free(str); + is_tester = false; + } + + if (is_tester) { + add_dependency_to_set(c, e); + array_add(&c->info.testing_procedures, e); + } + } + } else { + add_dependency_to_set(c, start); + } } bool is_entity_a_dependency(Entity *e) { @@ -4344,6 +4389,7 @@ void check_parsed_files(Checker *c) { string_map_set(&c->info.packages, p->fullpath, p); if (scope->flags&ScopeFlag_Init) { + c->info.init_package = p; c->info.init_scope = scope; } if (p->kind == Package_Runtime) { @@ -4613,7 +4659,7 @@ void check_parsed_files(Checker *c) { TIME_SECTION("check entry point"); - if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point) { + if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point && build_context.command_kind != Command_test) { Scope *s = c->info.init_scope; GB_ASSERT(s != nullptr); GB_ASSERT(s->flags&ScopeFlag_Init); diff --git a/src/checker.hpp b/src/checker.hpp index b986296e0..72c4b148c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -273,6 +273,7 @@ struct CheckerInfo { AstPackage * builtin_package; AstPackage * runtime_package; + AstPackage * init_package; Scope * init_scope; Entity * entry_point; PtrSet minimum_dependency_set; @@ -283,6 +284,7 @@ struct CheckerInfo { Map atom_op_map; // Key: Ast * + Array testing_procedures; bool allow_identifier_uses; Array identifier_uses; // only used by 'odin query' diff --git a/src/ir.cpp b/src/ir.cpp index 1f2819ccf..819442030 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -12781,11 +12781,18 @@ void ir_gen_tree(irGen *s) { ir_fill_slice(proc, global_args, argv, ir_emit_conv(proc, argc, t_int)); ir_emit(proc, ir_alloc_instr(proc, irInstr_StartupRuntime)); - { + Array empty_args = {}; + if (build_context.command_kind == Command_test) { + for_array(i, m->info->testing_procedures) { + Entity *e = m->info->testing_procedures[i]; + irValue **found = map_get(&proc->module->values, hash_entity(e)); + GB_ASSERT(found != nullptr); + ir_emit_call(proc, *found, empty_args); + } + } else { irValue **found = map_get(&proc->module->values, hash_entity(entry_point)); if (found != nullptr) { - Array args = {}; - ir_emit_call(proc, *found, args); + ir_emit_call(proc, *found, empty_args); } } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 50d200551..ea5081be4 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -12875,11 +12875,21 @@ void lb_generate_code(lbGenerator *gen) { lb_begin_procedure_body(p); - lbValue *found = map_get(&m->values, hash_entity(entry_point)); - GB_ASSERT(found != nullptr); - LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_runtime->type)), startup_runtime->value, nullptr, 0, ""); - LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, found->type)), found->value, nullptr, 0, ""); + + if (build_context.command_kind == Command_test) { + for_array(i, m->info->testing_procedures) { + Entity *e = m->info->testing_procedures[i]; + lbValue *found = map_get(&m->values, hash_entity(e)); + GB_ASSERT(found != nullptr); + lb_emit_call(p, *found, {}); + } + } else { + lbValue *found = map_get(&m->values, hash_entity(entry_point)); + GB_ASSERT(found != nullptr); + LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, found->type)), found->value, nullptr, 0, ""); + } + LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_i32), 0, false)); lb_end_procedure_body(p); diff --git a/src/main.cpp b/src/main.cpp index 5faedbccb..b83c420ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -675,7 +675,7 @@ ExactValue build_param_to_exact_value(String name, String param) { bool parse_build_flags(Array args) { auto build_flags = array_make(heap_allocator(), 0, BuildFlag_COUNT); add_flag(&build_flags, BuildFlag_Help, str_lit("help"), BuildFlagParam_None, Command_all); - add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String, Command__does_build &~ Command_test); add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer, Command__does_build); add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check); @@ -693,7 +693,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build); - add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test); add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build); add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None, Command__does_build); @@ -1540,6 +1540,8 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable."); } else if (command == "check") { print_usage_line(1, "check parse and type check .odin file"); + } else if (command == "test") { + print_usage_line(1, "test build ands runs 'test_*' procedures in the initial package"); } else if (command == "query") { print_usage_line(1, "query [experimental] parse, type check, and output a .json file containing information about the program"); } else if (command == "doc") { @@ -1550,9 +1552,9 @@ void print_show_help(String const arg0, String const &command) { bool doc = command == "doc"; bool build = command == "build"; - bool run_or_build = command == "run" || command == "build"; + bool run_or_build = command == "run" || command == "build" || command == "test"; bool check_only = command == "check"; - bool check = command == "run" || command == "build" || command == "check"; + bool check = run_or_build || command == "check"; print_usage_line(0, ""); print_usage_line(1, "Flags"); @@ -1850,12 +1852,15 @@ int main(int arg_count, char const **arg_ptr) { String run_args_string = {}; bool run_output = false; - if (command == "run") { + if (command == "run" || command == "test") { if (args.count < 3) { usage(args[0]); return 1; } build_context.command_kind = Command_run; + if (command == "test") { + build_context.command_kind = Command_test; + } Array run_args = array_make(heap_allocator(), 0, arg_count); defer (array_free(&run_args)); diff --git a/src/parser.hpp b/src/parser.hpp index 3be7939fa..48af0b293 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -107,6 +107,8 @@ struct AstFile { f64 time_to_tokenize; // seconds f64 time_to_parse; // seconds + bool is_test; + CommentGroup *lead_comment; // Comment (block) before the decl CommentGroup *line_comment; // Comment after the semicolon CommentGroup *docs; // current docs -- cgit v1.2.3 From 30765475c683c03ba587e51534feda756036e45f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 18:59:48 +0000 Subject: Fix up `system_exec_command_line_app` exit code code --- src/main.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index b83c420ae..40b26794f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -162,8 +162,11 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { #ifdef GB_SYSTEM_UNIX - system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s", - LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + exit_code = system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s", + LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + if (exit_code != 0) { + return exit_code; + } #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]), @@ -265,7 +268,7 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.resource_filepath) ); - if (exit_code != 0) { + if (exit_code != 0) { return exit_code; } @@ -283,6 +286,10 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.extra_linker_flags), lib_str ); + + if (exit_code != 0) { + return exit_code; + } } else { exit_code = system_exec_command_line_app("msvc-link", "\"%.*slink.exe\" %s -OUT:\"%.*s.%s\" %s " @@ -298,7 +305,10 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.extra_linker_flags), lib_str ); - } + + if (exit_code != 0) { + return exit_code; + } } } else { // lld exit_code = system_exec_command_line_app("msvc-link", "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s.%s\" %s " @@ -315,6 +325,10 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.extra_linker_flags), lib_str ); + + if (exit_code != 0) { + return exit_code; + } } #else timings_start_section(timings, str_lit("ld-link")); -- cgit v1.2.3 From ef2f204c58f355daf516c25e6e59dcd60bce444d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 20:33:15 +0000 Subject: Improve `system_exec_command_line_app` functionality; Restrict `test_*` procedures to `*_test.odin` files --- src/checker.cpp | 10 +++-- src/main.cpp | 111 +++++++++++++++----------------------------------------- 2 files changed, 36 insertions(+), 85 deletions(-) (limited to 'src/main.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 61b1e4bae..3339b6bfc 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1864,10 +1864,14 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { if (e->kind != Entity_Procedure) { continue; } + + if (e->file == nullptr || !e->file->is_test) { + continue; + } + String name = e->token.string; String prefix = str_lit("test_"); - if (!string_starts_with(name, prefix)) { continue; } @@ -1876,9 +1880,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { if (name != prefix) { is_tester = true; } else { - if (e->file && e->file->is_test) { - error(e->token, "Invalid testing procedure name: %.*s", LIT(name)); - } + error(e->token, "Invalid testing procedure name: %.*s", LIT(name)); } Type *t = base_type(e->type); diff --git a/src/main.cpp b/src/main.cpp index 40b26794f..7eef5d2ad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,6 +85,10 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { exit_code = -1; } + if (exit_code) { + exit(exit_code); + } + return exit_code; #elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX) @@ -133,6 +137,10 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { // exit_code = status; + if (exit_code) { + exit(exit_code); + } + return exit_code; #endif } @@ -141,32 +149,23 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { #if defined(LLVM_BACKEND_SUPPORT) -i32 linker_stage(lbGenerator *gen) { - i32 exit_code = 0; - +void linker_stage(lbGenerator *gen) { Timings *timings = &global_timings; String output_base = gen->output_base; if (build_context.metrics.os == TargetOs_js) { timings_start_section(timings, str_lit("wasm-ld")); - exit_code = system_exec_command_line_app("wasm-ld", + system_exec_command_line_app("wasm-ld", "\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm-obj\" -o \"%.*s.wasm\" %.*s %.*s", LIT(build_context.ODIN_ROOT), LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); - if (exit_code != 0) { - return exit_code; - } - return exit_code; } if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { #ifdef GB_SYSTEM_UNIX - exit_code = system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s", + system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s", LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); - if (exit_code != 0) { - return exit_code; - } #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]), @@ -197,7 +196,7 @@ i32 linker_stage(lbGenerator *gen) { if (find_result.windows_sdk_version == 0) { gb_printf_err("Windows SDK not found.\n"); - return 1; + exit(1); } if (build_context.ignore_microsoft_magic) { @@ -262,17 +261,13 @@ i32 linker_stage(lbGenerator *gen) { char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE"; if (!build_context.use_lld) { // msvc if (build_context.has_resource) { - exit_code = system_exec_command_line_app("msvc-link", + system_exec_command_line_app("msvc-link", "\"rc.exe\" /nologo /fo \"%.*s.res\" \"%.*s.rc\"", LIT(output_base), LIT(build_context.resource_filepath) ); - if (exit_code != 0) { - return exit_code; - } - - exit_code = system_exec_command_line_app("msvc-link", + system_exec_command_line_app("msvc-link", "\"%.*slink.exe\" %s \"%.*s.res\" -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " @@ -286,12 +281,8 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.extra_linker_flags), lib_str ); - - if (exit_code != 0) { - return exit_code; - } } else { - exit_code = system_exec_command_line_app("msvc-link", + system_exec_command_line_app("msvc-link", "\"%.*slink.exe\" %s -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " @@ -305,12 +296,9 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.extra_linker_flags), lib_str ); - - if (exit_code != 0) { - return exit_code; - } } + } } else { // lld - exit_code = system_exec_command_line_app("msvc-link", + system_exec_command_line_app("msvc-link", "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " @@ -325,10 +313,6 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.extra_linker_flags), lib_str ); - - if (exit_code != 0) { - return exit_code; - } } #else timings_start_section(timings, str_lit("ld-link")); @@ -433,7 +417,7 @@ i32 linker_stage(lbGenerator *gen) { } } - exit_code = system_exec_command_line_app("ld-link", + system_exec_command_line_app("ld-link", "%s %s -o \"%.*s%.*s\" %s " " %s " " %.*s " @@ -457,28 +441,21 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); - if (exit_code != 0) { - return exit_code; - } #if defined(GB_SYSTEM_OSX) if (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 - exit_code = system_exec_command_line_app("dsymutil", + system_exec_command_line_app("dsymutil", "dsymutil %.*s%.*s", LIT(output_base), LIT(output_ext) ); - - if (exit_code != 0) { - return exit_code; - } } #endif #endif } - return exit_code; + return; } #endif @@ -2070,12 +2047,7 @@ int main(int arg_count, char const **arg_ptr) { switch (build_context.build_mode) { case BuildMode_Executable: case BuildMode_DynamicLibrary: - { - i32 linker_stage_exit_count = linker_stage(&gen); - if (linker_stage_exit_count != 0) { - return linker_stage_exit_count; - } - } + linker_stage(&gen); break; } @@ -2159,19 +2131,11 @@ int main(int arg_count, char const **arg_ptr) { build_context.optimization_level = gb_clamp(build_context.optimization_level, 0, 3); - i32 exit_code = 0; - timings_start_section(timings, str_lit("llvm-opt")); - exit_code = exec_llvm_opt(output_base); - if (exit_code != 0) { - return exit_code; - } + exec_llvm_opt(output_base); timings_start_section(timings, str_lit("llvm-llc")); - exit_code = exec_llvm_llc(output_base); - if (exit_code != 0) { - return exit_code; - } + exec_llvm_llc(output_base); if (build_context.build_mode == BuildMode_Object) { // Ignore the linker @@ -2180,7 +2144,7 @@ int main(int arg_count, char const **arg_ptr) { } remove_temp_files(output_base); - return exit_code; + return 0; } if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { @@ -2277,17 +2241,13 @@ int main(int arg_count, char const **arg_ptr) { if (!build_context.use_lld) { // msvc if (build_context.has_resource) { - exit_code = system_exec_command_line_app("msvc-link", + system_exec_command_line_app("msvc-link", "\"rc.exe\" /nologo /fo \"%.*s.res\" \"%.*s.rc\"", LIT(output_base), LIT(build_context.resource_filepath) ); - if (exit_code != 0) { - return exit_code; - } - - exit_code = system_exec_command_line_app("msvc-link", + system_exec_command_line_app("msvc-link", "\"%.*slink.exe\" \"%.*s.obj\" \"%.*s.res\" -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " @@ -2302,7 +2262,7 @@ int main(int arg_count, char const **arg_ptr) { lib_str ); } else { - exit_code = system_exec_command_line_app("msvc-link", + system_exec_command_line_app("msvc-link", "\"%.*slink.exe\" \"%.*s.obj\" -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " @@ -2318,7 +2278,7 @@ int main(int arg_count, char const **arg_ptr) { ); } } else { // lld - exit_code = system_exec_command_line_app("msvc-link", + system_exec_command_line_app("msvc-link", "\"%.*s\\bin\\lld-link\" \"%.*s.obj\" -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " @@ -2335,10 +2295,6 @@ int main(int arg_count, char const **arg_ptr) { ); } - if (exit_code != 0) { - return exit_code; - } - if (build_context.show_timings) { show_timings(&checker, timings); } @@ -2447,7 +2403,7 @@ int main(int arg_count, char const **arg_ptr) { } - exit_code = system_exec_command_line_app("ld-link", + system_exec_command_line_app("ld-link", "%s \"%.*s.o\" -o \"%.*s%.*s\" %s " " %s " " %.*s " @@ -2471,21 +2427,14 @@ int main(int arg_count, char const **arg_ptr) { LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); - if (exit_code != 0) { - return exit_code; - } #if defined(GB_SYSTEM_OSX) if (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 - exit_code = system_exec_command_line_app("dsymutil", + system_exec_command_line_app("dsymutil", "dsymutil %.*s%.*s", LIT(output_base), LIT(output_ext) ); - - if (exit_code != 0) { - return exit_code; - } } #endif -- cgit v1.2.3 From 9408eb9580c1663195089ba18a53b704b382e40a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 18 Nov 2020 23:22:27 +0000 Subject: Update `odin doc` to support multiple package outputs by passing multiple paths; Replace `-all` with `-short` Example: odin doc core/path core/path/filepath --- core/path/match.odin | 2 - src/build_settings.cpp | 4 +- src/docs.cpp | 131 ++++++++++++++++++++++++++----------------------- src/main.cpp | 67 +++++++++++++------------ src/parser.cpp | 77 ++++++++++++++++++++++++----- src/parser.hpp | 1 + 6 files changed, 171 insertions(+), 111 deletions(-) (limited to 'src/main.cpp') diff --git a/core/path/match.odin b/core/path/match.odin index 555c1b05c..e77bf79c3 100644 --- a/core/path/match.odin +++ b/core/path/match.odin @@ -28,8 +28,6 @@ Match_Error :: enum { // match requires that the pattern matches the entirety of the name, not just a substring // The only possible error returned is .Syntax_Error // -// NOTE(bill): This is effectively the shell pattern matching system found -// match :: proc(pattern, name: string) -> (matched: bool, err: Match_Error) { pattern, name := pattern, name; pattern_loop: for len(pattern) > 0 { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 35dc9a7c1..c251cba53 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -130,7 +130,7 @@ char const *odin_command_strings[32] = { enum CmdDocFlag : u32 { - CmdDocFlag_All = 1<<0, + CmdDocFlag_Short = 1<<0, CmdDocFlag_AllPackages = 1<<1, }; @@ -200,7 +200,7 @@ struct BuildContext { bool linker_map_file; u32 cmd_doc_flags; - Array doc_packages; + Array extra_packages; QueryDataSetSettings query_data_set_settings; diff --git a/src/docs.cpp b/src/docs.cpp index d86f85c8d..aa1b89560 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -93,6 +93,8 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { isize count = 0; for_array(i, g->list) { String comment = g->list[i].string; + String original_comment = comment; + bool slash_slash = comment[1] == '/'; bool slash_star = comment[1] == '*'; if (comment[1] == '/') { @@ -113,15 +115,51 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { if (string_starts_with(comment, str_lit("+"))) { continue; } + if (string_starts_with(comment, str_lit("@("))) { + continue; + } } - if (string_starts_with(comment, str_lit("@("))) { - continue; + + if (slash_slash) { + print_doc_line(indent, "%.*s", LIT(comment)); + count += 1; + } else { + isize pos = 0; + for (; pos < comment.len; pos++) { + isize end = pos; + for (; end < comment.len; end++) { + if (comment[end] == '\n') { + break; + } + } + String line = substring(comment, pos, end); + pos = end+1; + String trimmed_line = string_trim_whitespace(line); + if (trimmed_line.len == 0) { + if (count == 0) { + continue; + } + } + /* + * Remove comments with + * styles + * like this + */ + if (string_starts_with(line, str_lit("* "))) { + line = substring(line, 2, line.len); + } + + print_doc_line(indent, "%.*s", LIT(line)); + count += 1; + } } + } - print_doc_line(indent, "%.*s", LIT(comment)); - count += 1; + if (count > 0) { + print_doc_line(0, ""); + return true; } - return count > 0; + return false; } @@ -129,10 +167,10 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { void print_doc_expr(Ast *expr) { gbString s = nullptr; - if (build_context.cmd_doc_flags & CmdDocFlag_All) { - s = expr_to_string(expr); - } else { + if (build_context.cmd_doc_flags & CmdDocFlag_Short) { s = expr_to_string_shorthand(expr); + } else { + s = expr_to_string(expr); } gb_file_write(gb_file_get_standard(gbFileStandard_Output), s, gb_string_length(s)); gb_string_free(s); @@ -151,9 +189,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { AstFile *f = pkg->files[i]; if (f->pkg_decl) { GB_ASSERT(f->pkg_decl->kind == Ast_PackageDecl); - if (print_doc_comment_group_string(1, f->pkg_decl->PackageDecl.docs)) { - print_doc_line(0, ""); - } + print_doc_comment_group_string(1, f->pkg_decl->PackageDecl.docs); } } @@ -182,6 +218,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { } gb_sort_array(entities.data, entities.count, cmp_entities_for_printing); + bool show_docs = (build_context.cmd_doc_flags & CmdDocFlag_Short) == 0; + EntityKind curr_entity_kind = Entity_Invalid; for_array(i, entities) { Entity *e = entities[i]; @@ -192,6 +230,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { continue; } + if (curr_entity_kind != e->kind) { if (curr_entity_kind != Entity_Invalid) { print_doc_line(0, ""); @@ -213,6 +252,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { docs = e->decl_info->docs; } GB_ASSERT(type_expr != nullptr || init_expr != nullptr); + print_doc_line_no_newline(2, "%.*s", LIT(e->token.string)); if (type_expr != nullptr) { gbString t = expr_to_string(type_expr); @@ -233,14 +273,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { gb_printf(";\n"); - - if (build_context.cmd_doc_flags & CmdDocFlag_All) { - if (comment) { - // gb_printf(" "); - } - if (print_doc_comment_group_string(3, docs)) { - gb_printf("\n"); - } + if (show_docs) { + print_doc_comment_group_string(3, docs); } } print_doc_line(0, ""); @@ -248,7 +282,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { if (pkg->fullpath.len != 0) { print_doc_line(0, ""); - print_doc_line(1, "fullpath: %.*s", LIT(pkg->fullpath)); + print_doc_line(1, "fullpath:"); + print_doc_line(2, "%.*s", LIT(pkg->fullpath)); print_doc_line(1, "files:"); for_array(i, pkg->files) { AstFile *f = pkg->files[i]; @@ -262,51 +297,23 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { void generate_documentation(Checker *c) { CheckerInfo *info = &c->info; - if (build_context.doc_packages.count != 0) { - auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); - bool was_error = false; - for_array(j, build_context.doc_packages) { - bool found = false; - String name = build_context.doc_packages[j]; - for_array(i, info->packages.entries) { - AstPackage *pkg = info->packages.entries[i].value; - if (name == pkg->name) { - found = true; - array_add(&pkgs, pkg); - break; - } - } - if (!found) { - gb_printf_err("Unknown package %.*s\n", LIT(name)); - was_error = true; - } - } - if (was_error) { - gb_exit(1); - return; - } - - gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); - - for_array(i, pkgs) { - print_doc_package(info, pkgs[i]); - } - } else if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) { - auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); - for_array(i, info->packages.entries) { - AstPackage *pkg = info->packages.entries[i].value; + auto pkgs = array_make(permanent_allocator(), 0, info->packages.entries.count); + for_array(i, info->packages.entries) { + AstPackage *pkg = info->packages.entries[i].value; + if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) { array_add(&pkgs, pkg); + } else { + if (pkg->kind == Package_Init) { + array_add(&pkgs, pkg); + } else if (pkg->is_extra) { + array_add(&pkgs, pkg); + } } + } - gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); - - for_array(i, pkgs) { - print_doc_package(info, pkgs[i]); - } - } else { - GB_ASSERT(info->init_scope->flags & ScopeFlag_Pkg); - AstPackage *pkg = info->init_scope->pkg; - print_doc_package(info, pkg); + gb_sort_array(pkgs.data, pkgs.count, cmp_ast_package_by_name); + for_array(i, pkgs) { + print_doc_package(info, pkgs[i]); } } diff --git a/src/main.cpp b/src/main.cpp index 7eef5d2ad..dbade085d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -589,8 +589,7 @@ enum BuildFlagKind { BuildFlag_GlobalDefinitions, BuildFlag_GoToDefinitions, - BuildFlag_Package, - BuildFlag_All, + BuildFlag_Short, BuildFlag_AllPackages, #if defined(GB_SYSTEM_WINDOWS) @@ -699,9 +698,8 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_Package, str_lit("package"), BuildFlagParam_String, Command_doc, true); - add_flag(&build_flags, BuildFlag_All, str_lit("all"), BuildFlagParam_None, Command_doc); - add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); + add_flag(&build_flags, BuildFlag_Short, str_lit("short"), BuildFlagParam_None, Command_doc); + add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); #if defined(GB_SYSTEM_WINDOWS) @@ -852,7 +850,7 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); String path = value.value_string; path = string_trim_whitespace(path); - if (is_import_path_valid(path)) { + if (is_build_flag_path_valid(path)) { #if defined(GB_SYSTEM_WINDOWS) String ext = path_extension(path); if (ext == ".exe") { @@ -1191,22 +1189,15 @@ bool parse_build_flags(Array args) { } break; - case BuildFlag_Package: - GB_ASSERT(value.kind == ExactValue_String); - if (value.value_string.len == 0) { - gb_printf_err("Invalid use of -package flag\n"); - } else { - array_add(&build_context.doc_packages, value.value_string); - } - break; - case BuildFlag_All: - build_context.cmd_doc_flags |= CmdDocFlag_All; + case BuildFlag_Short: + build_context.cmd_doc_flags |= CmdDocFlag_Short; break; case BuildFlag_AllPackages: build_context.cmd_doc_flags |= CmdDocFlag_AllPackages; break; + #if defined(GB_SYSTEM_WINDOWS) case BuildFlag_IgnoreVsSearch: GB_ASSERT(value.kind == ExactValue_Invalid); @@ -1217,7 +1208,7 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); String path = value.value_string; path = string_trim_whitespace(path); - if (is_import_path_valid(path)) { + if (is_build_flag_path_valid(path)) { if(!string_ends_with(path, str_lit(".rc"))) { gb_printf_err("Invalid -resource path %.*s, missing .rc\n", LIT(path)); bad_flags = true; @@ -1235,7 +1226,7 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); String path = value.value_string; path = string_trim_whitespace(path); - if (is_import_path_valid(path)) { + if (is_build_flag_path_valid(path)) { // #if defined(GB_SYSTEM_WINDOWS) // String ext = path_extension(path); // if (ext != ".pdb") { @@ -1299,12 +1290,6 @@ bool parse_build_flags(Array args) { } } - if (build_context.doc_packages.count > 0 && set_flags[BuildFlag_AllPackages]) { - gb_printf_err("'odin doc' does not allow both flags together '-all-packages' and '-package' together");; - bad_flags = true; - } - - if (build_context.query_data_set_settings.ok) { if (build_context.query_data_set_settings.kind == QueryDataSet_Invalid) { gb_printf_err("'odin query' requires a flag determining the kind of query data set to be returned\n"); @@ -1537,6 +1522,9 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "query [experimental] parse, type check, and output a .json file containing information about the program"); } else if (command == "doc") { print_usage_line(1, "doc generate documentation from a .odin file, or directory of .odin files"); + print_usage_line(2, "Examples:"); + print_usage_line(3, "odin doc core/path"); + print_usage_line(3, "odin doc core/path core/path/filepath"); } else if (command == "version") { print_usage_line(1, "version print version"); } @@ -1552,14 +1540,8 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(0, ""); if (doc) { - print_usage_line(1, "-all"); - print_usage_line(2, "Show all documentation for the packages"); - print_usage_line(0, ""); - - print_usage_line(1, "-package:"); - print_usage_line(2, "Add package name to generate documentation for"); - print_usage_line(2, "Multiple flags are allowed"); - print_usage_line(2, "Example: -doc:runtime"); + print_usage_line(1, "-short"); + print_usage_line(2, "Show shortened documentation for the packages"); print_usage_line(0, ""); print_usage_line(1, "-all-packages"); @@ -1833,7 +1815,7 @@ int main(int arg_count, char const **arg_ptr) { add_library_collection(str_lit("core"), get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("core"))); map_init(&build_context.defined_values, heap_allocator()); - build_context.doc_packages.allocator = heap_allocator(); + build_context.extra_packages.allocator = heap_allocator(); Array args = setup_args(arg_count, arg_ptr); @@ -1904,6 +1886,20 @@ int main(int arg_count, char const **arg_ptr) { build_context.command_kind = Command_doc; init_filename = args[2]; + for (isize i = 3; i < args.count; i++) { + auto arg = args[i]; + if (string_starts_with(arg, str_lit("-"))) { + break; + } + array_add(&build_context.extra_packages, arg); + } + isize extra_count = build_context.extra_packages.count; + if (extra_count > 0) { + gb_memmove(args.data + 3, args.data + 3 + extra_count, extra_count * gb_size_of(*args.data)); + args.count -= extra_count; + } + + build_context.no_output_files = true; build_context.generate_docs = true; build_context.no_entry_point = true; // ignore entry point @@ -2005,8 +2001,11 @@ int main(int arg_count, char const **arg_ptr) { temp_allocator_free_all(&temporary_allocator_data); if (build_context.generate_docs) { + if (global_error_collector.count != 0) { + return 1; + } generate_documentation(&checker); - return global_error_collector.count ? 1 : 0; + return 0; } if (build_context.no_output_files) { diff --git a/src/parser.cpp b/src/parser.cpp index 9e9708f9c..ec38dca9b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4653,14 +4653,14 @@ void parser_add_foreign_file_to_process(Parser *p, AstPackage *pkg, AstForeignFi // NOTE(bill): Returns true if it's added -bool try_add_import_path(Parser *p, String const &path, String const &rel_path, TokenPos pos, PackageKind kind = Package_Normal) { +AstPackage *try_add_import_path(Parser *p, String const &path, String const &rel_path, TokenPos pos, PackageKind kind = Package_Normal) { String const FILE_EXT = str_lit(".odin"); gb_mutex_lock(&p->file_add_mutex); defer (gb_mutex_unlock(&p->file_add_mutex)); if (string_set_exists(&p->imported_files, path)) { - return false; + return nullptr; } string_set_add(&p->imported_files, path); @@ -4683,7 +4683,7 @@ bool try_add_import_path(Parser *p, String const &path, String const &rel_path, pkg->is_single_file = true; parser_add_file_to_process(p, pkg, fi, pos); parser_add_package(p, pkg); - return true; + return pkg; } @@ -4699,22 +4699,22 @@ bool try_add_import_path(Parser *p, String const &path, String const &rel_path, switch (rd_err) { case ReadDirectory_InvalidPath: syntax_error(pos, "Invalid path: %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_NotExists: syntax_error(pos, "Path does not exist: %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_Permission: syntax_error(pos, "Unknown error whilst reading path %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_NotDir: syntax_error(pos, "Expected a directory for a package, got a file: %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_Empty: syntax_error(pos, "Empty directory: %.*s", LIT(rel_path)); - return false; + return nullptr; case ReadDirectory_Unknown: syntax_error(pos, "Unknown error whilst reading path %.*s", LIT(rel_path)); - return false; + return nullptr; } for_array(list_index, list) { @@ -4736,7 +4736,7 @@ bool try_add_import_path(Parser *p, String const &path, String const &rel_path, parser_add_package(p, pkg); - return true; + return pkg; } gb_global Rune illegal_import_runes[] = { @@ -4755,7 +4755,7 @@ bool is_import_path_valid(String path) { u8 *curr = start; while (curr < end) { isize width = 1; - Rune r = curr[0]; + Rune r = *curr; if (r >= 0x80) { width = gb_utf8_decode(curr, end-curr, &r); if (r == GB_RUNE_INVALID && width == 1) { @@ -4780,6 +4780,45 @@ bool is_import_path_valid(String path) { return false; } +bool is_build_flag_path_valid(String path) { + if (path.len > 0) { + u8 *start = path.text; + u8 *end = path.text + path.len; + u8 *curr = start; + isize index = 0; + while (curr < end) { + isize width = 1; + Rune r = *curr; + if (r >= 0x80) { + width = gb_utf8_decode(curr, end-curr, &r); + if (r == GB_RUNE_INVALID && width == 1) { + return false; + } + else if (r == GB_RUNE_BOM && curr-start > 0) { + return false; + } + } + + for (isize i = 0; i < gb_count_of(illegal_import_runes); i++) { +#if defined(GB_SYSTEM_WINDOWS) + if (r == '\\') { + break; + } +#endif + if (r == illegal_import_runes[i]) { + return false; + } + } + + curr += width; + index += 1; + } + + return true; + } + return false; +} + bool is_package_name_reserved(String const &name) { if (name == "builtin") { @@ -5263,6 +5302,22 @@ ParseFileError parse_packages(Parser *p, String init_filename) { try_add_import_path(p, init_fullpath, init_fullpath, init_pos, Package_Init); p->init_fullpath = init_fullpath; + for_array(i, build_context.extra_packages) { + String path = build_context.extra_packages[i]; + String fullpath = path_to_full_path(heap_allocator(), path); // LEAK? + if (!path_is_directory(fullpath)) { + String const ext = str_lit(".odin"); + if (!string_ends_with(fullpath, ext)) { + error_line("Expected either a directory or a .odin file, got '%.*s'\n", LIT(fullpath)); + return ParseFile_WrongExtension; + } + } + AstPackage *pkg = try_add_import_path(p, fullpath, fullpath, init_pos, Package_Normal); + if (pkg) { + pkg->is_extra = true; + } + } + thread_pool_start(&parser_thread_pool); thread_pool_wait_to_process(&parser_thread_pool); diff --git a/src/parser.hpp b/src/parser.hpp index 48af0b293..aa288304e 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -150,6 +150,7 @@ struct AstPackage { Scope * scope; DeclInfo *decl_info; bool used; + bool is_extra; }; -- cgit v1.2.3 From dbaf4d24f6e67ec05e8640b037cd934121f125c5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 25 Nov 2020 16:19:56 +0000 Subject: Update package json for new map layout; Correct llvm-api includes for *nix --- core/encoding/json/marshal.odin | 8 ++++---- src/llvm_backend.cpp | 4 ++++ src/llvm_backend.hpp | 19 +++++++++++++++++++ src/main.cpp | 4 ++++ 4 files changed, 31 insertions(+), 4 deletions(-) (limited to 'src/main.cpp') diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 92b18c9e3..4df827ad4 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -210,12 +210,12 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error { data := uintptr(entries.data) + uintptr(i*entry_size); header := cast(^Map_Entry_Header)data; - marshal_arg(b, any{rawptr(&header.key.key.val), info.key.id}); + key := rawptr(data + entry_type.offsets[2]); + value := rawptr(data + entry_type.offsets[3]); + marshal_arg(b, any{key, info.key.id}); write_string(b, ": "); - - value := data + entry_type.offsets[2]; - marshal_arg(b, any{rawptr(value), info.value.id}); + marshal_arg(b, any{value, info.value.id}); } } write_byte(b, '}'); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index f8c6b44e1..2d5e14c68 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -12522,6 +12522,10 @@ void lb_generate_code(lbGenerator *gen) { 1, "", 0, LLVMDWARFEmissionFull, 0, true, true + #if LLVM_VERSION_MAJOR > 10 + , "", 0, + "", 0 + #endif ); } diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 388176e9a..09929c8cd 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -1,3 +1,5 @@ +#if defined(LLVM_BACKEND_SUPPORT) +#if defined(GB_SYSTEM_WINDOWS) #include "llvm-c/Core.h" #include "llvm-c/ExecutionEngine.h" #include "llvm-c/Target.h" @@ -12,6 +14,23 @@ #include "llvm-c/Transforms/Scalar.h" #include "llvm-c/Transforms/Utils.h" #include "llvm-c/Transforms/Vectorize.h" +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#endif struct lbProcedure; diff --git a/src/main.cpp b/src/main.cpp index dbade085d..fbcc03dae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,7 +11,11 @@ gb_global Timings global_timings = {0}; #if defined(LLVM_BACKEND_SUPPORT) +#if defined(GB_SYSTEM_WINDOWS) #include "llvm-c/Types.h" +#else +#include +#endif #endif #include "parser.hpp" -- cgit v1.2.3