diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index afd4d00ece..f06443a215 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -183,17 +183,19 @@ to create a copy of the compiler rather than replacing it with `v self`. | Flag | Usage | |------|-------| -| `debugautostr` | Prints informations about `.str()` method auto-generated by the compiler during C generation | | `debugscanner` | Prints debug information during the scanning phase | | `debug_codegen` | Prints automatically generated V code during the scanning phase | | `debug_interface_table` | Prints generated interfaces during C generation | | `debug_interface_type_implements` | Prints debug information when checking that a type implements in interface | +| `debug_embed_file_in_prod` | Prints debug information about the embedded files with `$embed_file('somefile')` | | `print_vweb_template_expansions` | Prints vweb compiled HTML files | -| `time_checking` | Prints the time spent checking files and other related informations | -| `time_parsing` | Prints the time spent parsing files and other related informations | +| `time_checking` | Prints the time spent checking files and other related information | +| `time_parsing` | Prints the time spent parsing files and other related information | +| `trace_autofree` | Prints details about how/when -autofree puts free() calls | +| `trace_autostr` | Prints details about `.str()` method auto-generated by the compiler during C generation | | `trace_ccoptions` | Prints options passed down to the C compiler | -| `trace_checker` | Prints informations about the statements being checked | +| `trace_checker` | Prints details about the statements being checked | | `trace_gen` | Prints strings written to the generated C file. Beware, this flag is very verbose | -| `trace_parser` | Prints informations about parsed statements and expressions | -| `trace_thirdparty_obj_files` | Prints informations about built thirdparty obj files | -| `trace_use_cache` | Prints informations about cache use | +| `trace_parser` | Prints details about parsed statements and expressions | +| `trace_thirdparty_obj_files` | Prints details about built thirdparty obj files | +| `trace_usecache` | Prints details when -usecache is used | diff --git a/doc/docs.md b/doc/docs.md index bdcc7abe2f..3a1a3e0b73 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -4956,7 +4956,7 @@ Full list of builtin options: | `windows`, `linux`, `macos` | `gcc`, `tinyc` | `amd64`, `arm64` | `debug`, `prod`, `test` | | `mac`, `darwin`, `ios`, | `clang`, `mingw` | `x64`, `x32` | `js`, `glibc`, `prealloc` | | `android`,`mach`, `dragonfly` | `msvc` | `little_endian` | `no_bounds_checking`, `freestanding` | -| `gnu`, `hpux`, `haiku`, `qnx` | `cplusplus` | `big_endian` | +| `gnu`, `hpux`, `haiku`, `qnx` | `cplusplus` | `big_endian` | `no_segfault_handler`, `no_backtrace`, `no_main` | | `solaris` | | | | #### `$embed_file` diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index b5e159d425..0fe364d75f 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -87,6 +87,9 @@ fn should_use_indent_func(kind ast.Kind) bool { } fn (mut g Gen) gen_str_default(sym ast.TypeSymbol, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_default: $sym.name | $styp | str_fn_name') + } mut convertor := '' mut typename_ := '' if sym.parent_idx in ast.integer_type_idxs { @@ -124,6 +127,9 @@ mut: } fn (mut g Gen) get_str_fn(typ ast.Type) string { + $if trace_autostr ? { + eprintln('> get_str_fn: $typ.debug()') + } mut unwrapped := g.unwrap_generic(typ).set_nr_muls(0).clear_flag(.variadic) if g.pref.nofloat { if typ == ast.f32_type { @@ -158,6 +164,9 @@ fn (mut g Gen) final_gen_str(typ StrType) { if typ in g.generated_str_fns { return } + $if trace_autostr ? { + eprintln('> final_gen_str: $typ') + } g.generated_str_fns << typ sym := g.table.get_type_symbol(typ.typ) if sym.has_method_with_generic_parent('str') && !typ.typ.has_flag(.optional) { @@ -217,6 +226,9 @@ fn (mut g Gen) final_gen_str(typ StrType) { } fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_option: $typ.debug() | $styp | $str_fn_name') + } parent_type := typ.clear_flag(.optional) sym := g.table.get_type_symbol(parent_type) sym_has_str_method, _, _ := sym.str_method_info() @@ -248,6 +260,9 @@ fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string) fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string) { parent_str_fn_name := g.get_str_fn(info.parent_type) + $if trace_autostr ? { + eprintln('> gen_str_for_alias: $parent_str_fn_name | $styp | $str_fn_name') + } mut clean_type_v_type_name := util.strip_main_name(styp.replace('__', '.')) g.type_definitions.writeln('static string ${str_fn_name}($styp it); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp it) { return indent_${str_fn_name}(it, 0); }') @@ -267,6 +282,9 @@ fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string } fn (mut g Gen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_multi_return: $info.types | $styp | $str_fn_name') + } g.type_definitions.writeln('static string ${str_fn_name}($styp a); // auto') mut fn_builder := strings.new_builder(512) fn_builder.writeln('static string ${str_fn_name}($styp a) {') @@ -311,6 +329,9 @@ fn (mut g Gen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str_f } fn (mut g Gen) gen_str_for_enum(info ast.Enum, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_enum: $info | $styp | $str_fn_name') + } s := util.no_dots(styp) g.type_definitions.writeln('static string ${str_fn_name}($styp it); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp it) { /* gen_str_for_enum */') @@ -343,6 +364,9 @@ fn (mut g Gen) gen_str_for_enum(info ast.Enum, styp string, str_fn_name string) } fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_interface: $info.types | $styp | $str_fn_name') + } // _str() functions should have a single argument, the indenting ones take 2: g.type_definitions.writeln('static string ${str_fn_name}($styp x); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp x) { return indent_${str_fn_name}(x, 0); }') @@ -401,6 +425,9 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_nam } fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_union_sum_type: $info.variants | $styp | $str_fn_name') + } // _str() functions should have a single argument, the indenting ones take 2: g.type_definitions.writeln('static string ${str_fn_name}($styp x); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp x) { return indent_${str_fn_name}(x, 0); }') @@ -485,17 +512,26 @@ fn (mut g Gen) fn_decl_str(info ast.FnType) string { } fn (mut g Gen) gen_str_for_fn_type(info ast.FnType, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_fn_type: $info.func.name | $styp | $str_fn_name') + } g.type_definitions.writeln('static string ${str_fn_name}(); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}() { return _SLIT("${g.fn_decl_str(info)}");}') } fn (mut g Gen) gen_str_for_chan(info ast.Chan, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_chan: $info.elem_type.debug() | $styp | $str_fn_name') + } elem_type_name := util.strip_main_name(g.table.get_type_name(g.unwrap_generic(info.elem_type))) g.type_definitions.writeln('static string ${str_fn_name}($styp x); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp x) { return sync__Channel_auto_str(x, _SLIT("$elem_type_name")); }') } fn (mut g Gen) gen_str_for_thread(info ast.Thread, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_thread: $info.return_type.debug() | $styp | $str_fn_name') + } ret_type_name := util.strip_main_name(g.table.get_type_name(info.return_type)) g.type_definitions.writeln('static string ${str_fn_name}($styp _); // auto}') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp _) { return _SLIT("thread($ret_type_name)");}') @@ -519,6 +555,9 @@ fn deref_kind(str_method_expects_ptr bool, is_elem_ptr bool, typ ast.Type) (stri } fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_array: $info.elem_type.debug() | $styp | $str_fn_name') + } mut typ := info.elem_type mut sym := g.table.get_type_symbol(info.elem_type) if mut sym.info is ast.Alias { @@ -592,6 +631,9 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string } fn (mut g Gen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_array_fixed: $info.elem_type.debug() | $styp | $str_fn_name') + } mut typ := info.elem_type mut sym := g.table.get_type_symbol(info.elem_type) if mut sym.info is ast.Alias { @@ -652,6 +694,9 @@ fn (mut g Gen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_fn_ } fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_map: $info.key_type.debug() -> $info.value_type.debug() | $styp | $str_fn_name') + } mut key_typ := info.key_type mut key_sym := g.table.get_type_symbol(key_typ) if mut key_sym.info is ast.Alias { @@ -772,6 +817,9 @@ fn (g &Gen) type_to_fmt(typ ast.Type) StrIntpType { } fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name string) { + $if trace_autostr ? { + eprintln('> gen_str_for_struct: $info.parent_type.debug() | $styp | $str_fn_name') + } // _str() functions should have a single argument, the indenting ones take 2: g.type_definitions.writeln('static string ${str_fn_name}($styp it); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp it) { return indent_${str_fn_name}(it, 0);}') @@ -896,6 +944,9 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri } fn struct_auto_str_func(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string, has_custom_str bool, expects_ptr bool) (string, bool) { + $if trace_autostr ? { + eprintln('> struct_auto_str_func: $sym.name | field_type.debug() | $fn_name | $field_name | $has_custom_str | $expects_ptr') + } deref, _ := deref_kind(expects_ptr, field_type.is_ptr(), field_type) if sym.kind == .enum_ { return '${fn_name}(${deref}it.${c_name(field_name)})', true diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index acdecba6f7..2fccd3cc77 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -6242,8 +6242,10 @@ fn (mut g Gen) write_init_function() { // ___argv is declared as voidptr here, because that unifies the windows/unix logic g.writeln('void _vinit(int ___argc, voidptr ___argv) {') - // 11 is SIGSEGV. It is hardcoded here, to avoid FreeBSD compilation errors for trivial examples. - g.writeln('#if __STDC_HOSTED__ == 1\n\tsignal(11, v_segmentation_fault_handler);\n#endif') + if 'no_segfault_handler' !in g.pref.compile_defines { + // 11 is SIGSEGV. It is hardcoded here, to avoid FreeBSD compilation errors for trivial examples. + g.writeln('#if __STDC_HOSTED__ == 1\n\tsignal(11, v_segmentation_fault_handler);\n#endif') + } if g.pref.prealloc { g.writeln('prealloc_vinit();') } diff --git a/vlib/v/gen/c/cmain.v b/vlib/v/gen/c/cmain.v index 30c57303ea..e8e2cb08a5 100644 --- a/vlib/v/gen/c/cmain.v +++ b/vlib/v/gen/c/cmain.v @@ -14,6 +14,9 @@ pub fn (mut g Gen) gen_c_main() { // no main in .o files return } + if 'no_main' in g.pref.compile_defines { + return + } g.out.writeln('') main_fn_start_pos := g.out.len diff --git a/vlib/v/vcache/vcache.v b/vlib/v/vcache/vcache.v index 9ce75b6626..15fe3d7164 100644 --- a/vlib/v/vcache/vcache.v +++ b/vlib/v/vcache/vcache.v @@ -123,7 +123,7 @@ pub fn (mut cm CacheManager) load(postfix string, key string) ?string { return content } -[if trace_use_cache ?] +[if trace_usecache ?] pub fn dlog(fname string, s string) { pid := unsafe { mypid() } if fname[0] != `|` {