cgen: support `-d no_segfault_handler` and `-d no_main`. Cleanup `-d trace_xxx` descriptions in CONTRIBUTING.md

pull/12714/head
Delyan Angelov 2021-12-03 19:01:45 +02:00
parent 1d6cc57d9c
commit 4624de6cb5
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
6 changed files with 69 additions and 11 deletions

View File

@ -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 |

View File

@ -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`

View File

@ -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

View File

@ -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) {')
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();')
}

View File

@ -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

View File

@ -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] != `|` {