cgen: minor cleanup of gen_fn_decl (#8474)

pull/8499/head
yuyi 2021-02-02 03:06:34 +08:00 committed by GitHub
parent fab7b9d9d9
commit 4d268d1436
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 33 additions and 33 deletions

View File

@ -7,18 +7,18 @@ import v.ast
import v.table import v.table
import v.util import v.util
fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) { fn (mut g Gen) gen_fn_decl(node ast.FnDecl, skip bool) {
// TODO For some reason, build fails with autofree with this line // TODO For some reason, build fails with autofree with this line
// as it's only informative, comment it for now // as it's only informative, comment it for now
// g.gen_attrs(it.attrs) // g.gen_attrs(it.attrs)
if it.language == .c { if node.language == .c {
// || it.no_body { // || node.no_body {
return return
} }
g.returned_var_name = '' g.returned_var_name = ''
// //
old_g_autofree := g.is_autofree old_g_autofree := g.is_autofree
if it.is_manualfree { if node.is_manualfree {
g.is_autofree = false g.is_autofree = false
} }
defer { defer {
@ -26,49 +26,49 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
} }
// //
// if g.fileis('vweb.v') { // if g.fileis('vweb.v') {
// println('\ngen_fn_decl() $it.name $it.is_generic $g.cur_generic_type') // println('\ngen_fn_decl() $node.name $node.is_generic $g.cur_generic_type')
// } // }
if it.generic_params.len > 0 && g.cur_generic_types.len == 0 { // need the cur_generic_type check to avoid inf. recursion if node.generic_params.len > 0 && g.cur_generic_types.len == 0 { // need the cur_generic_type check to avoid inf. recursion
// loop thru each generic type and generate a function // loop thru each generic type and generate a function
for gen_types in g.table.fn_gen_types[it.name] { for gen_types in g.table.fn_gen_types[node.name] {
if g.pref.is_verbose { if g.pref.is_verbose {
syms := gen_types.map(g.table.get_type_symbol(it)) syms := gen_types.map(g.table.get_type_symbol(it))
println('gen fn `$it.name` for type `${syms.map(it.name).join(', ')}`') println('gen fn `$node.name` for type `${syms.map(node.name).join(', ')}`')
} }
g.cur_generic_types = gen_types g.cur_generic_types = gen_types
g.gen_fn_decl(it, skip) g.gen_fn_decl(node, skip)
} }
g.cur_generic_types = [] g.cur_generic_types = []
return return
} }
g.cur_fn = it g.cur_fn = node
fn_start_pos := g.out.len fn_start_pos := g.out.len
g.write_v_source_line_info(it.pos) g.write_v_source_line_info(node.pos)
msvc_attrs := g.write_fn_attrs(it.attrs) msvc_attrs := g.write_fn_attrs(node.attrs)
// Live // Live
is_livefn := it.attrs.contains('live') is_livefn := node.attrs.contains('live')
is_livemain := g.pref.is_livemain && is_livefn is_livemain := g.pref.is_livemain && is_livefn
is_liveshared := g.pref.is_liveshared && is_livefn is_liveshared := g.pref.is_liveshared && is_livefn
is_livemode := g.pref.is_livemain || g.pref.is_liveshared is_livemode := g.pref.is_livemain || g.pref.is_liveshared
is_live_wrap := is_livefn && is_livemode is_live_wrap := is_livefn && is_livemode
if is_livefn && !is_livemode { if is_livefn && !is_livemode {
eprintln('INFO: compile with `v -live $g.pref.path `, if you want to use the [live] function $it.name .') eprintln('INFO: compile with `v -live $g.pref.path `, if you want to use the [live] function $node.name .')
} }
// //
mut name := it.name mut name := node.name
if name in ['+', '-', '*', '/', '%', '<', '>', '==', '!=', '<=', '>='] { if name in ['+', '-', '*', '/', '%', '<', '>', '==', '!=', '<=', '>='] {
name = util.replace_op(name) name = util.replace_op(name)
} }
if it.is_method { if node.is_method {
name = g.cc_type2(it.receiver.typ) + '_' + name name = g.cc_type2(node.receiver.typ) + '_' + name
// name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name // name = g.table.get_type_symbol(node.receiver.typ).name + '_' + name
} }
if it.language == .c { if node.language == .c {
name = util.no_dots(name) name = util.no_dots(name)
} else { } else {
name = c_name(name) name = c_name(name)
} }
mut type_name := g.typ(it.return_type) mut type_name := g.typ(node.return_type)
if g.cur_generic_types.len > 0 { if g.cur_generic_types.len > 0 {
// foo<T>() => foo_T_int(), foo_T_string() etc // foo<T>() => foo_T_int(), foo_T_string() etc
// Using _T_ to differentiate between get<string> and get_string // Using _T_ to differentiate between get<string> and get_string
@ -107,7 +107,7 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
g.write('$type_name ${impl_fn_name}(') g.write('$type_name ${impl_fn_name}(')
} }
} else { } else {
if !(it.is_pub || g.pref.is_debug) { if !(node.is_pub || g.pref.is_debug) {
// Private functions need to marked as static so that they are not exportable in the // Private functions need to marked as static so that they are not exportable in the
// binaries // binaries
if g.pref.build_mode != .build_module && !g.pref.use_cache { if g.pref.build_mode != .build_module && !g.pref.use_cache {
@ -126,15 +126,15 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
g.definitions.write(fn_header) g.definitions.write(fn_header)
g.write(fn_header) g.write(fn_header)
} }
for param in it.params { for param in node.params {
if param.is_mut { if param.is_mut {
g.fn_mut_arg_names << param.name g.fn_mut_arg_names << param.name
} }
} }
arg_start_pos := g.out.len arg_start_pos := g.out.len
fargs, fargtypes := g.fn_args(it.params, it.is_variadic) fargs, fargtypes := g.fn_args(node.params, node.is_variadic)
arg_str := g.out.after(arg_start_pos) arg_str := g.out.after(arg_start_pos)
if it.no_body || ((g.pref.use_cache && g.pref.build_mode != .build_module) && it.is_builtin if node.no_body || ((g.pref.use_cache && g.pref.build_mode != .build_module) && node.is_builtin
&& !g.is_test)|| skip { && !g.is_test)|| skip {
// Just a function header. Builtin function bodies are defined in builtin.o // Just a function header. Builtin function bodies are defined in builtin.o
g.definitions.writeln(');') // // NO BODY') g.definitions.writeln(');') // // NO BODY')
@ -169,30 +169,30 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
} }
// Profiling mode? Start counting at the beginning of the function (save current time). // Profiling mode? Start counting at the beginning of the function (save current time).
if g.pref.is_prof && g.pref.build_mode != .build_module { if g.pref.is_prof && g.pref.build_mode != .build_module {
g.profile_fn(it) g.profile_fn(node)
} }
// we could be in an anon fn so save outer fn defer stmts // we could be in an anon fn so save outer fn defer stmts
prev_defer_stmts := g.defer_stmts prev_defer_stmts := g.defer_stmts
g.defer_stmts = [] g.defer_stmts = []
g.stmts(it.stmts) g.stmts(node.stmts)
// clear g.fn_mut_arg_names // clear g.fn_mut_arg_names
if g.fn_mut_arg_names.len > 0 { if g.fn_mut_arg_names.len > 0 {
g.fn_mut_arg_names.clear() g.fn_mut_arg_names.clear()
} }
if it.return_type == table.void_type { if node.return_type == table.void_type {
g.write_defer_stmts_when_needed() g.write_defer_stmts_when_needed()
} }
if it.is_anon { if node.is_anon {
g.defer_stmts = prev_defer_stmts g.defer_stmts = prev_defer_stmts
} else { } else {
g.defer_stmts = [] g.defer_stmts = []
} }
if it.return_type != table.void_type && it.stmts.len > 0 && it.stmts.last() !is ast.Return { if node.return_type != table.void_type && node.stmts.len > 0 && node.stmts.last() !is ast.Return {
default_expr := g.type_default(it.return_type) default_expr := g.type_default(node.return_type)
// TODO: perf? // TODO: perf?
if default_expr == '{0}' { if default_expr == '{0}' {
if it.return_type.idx() == 1 && it.return_type.has_flag(.optional) { if node.return_type.idx() == 1 && node.return_type.has_flag(.optional) {
// The default return for anonymous functions that return `?, // The default return for anonymous functions that return `?,
// should have .ok = true set, otherwise calling them with // should have .ok = true set, otherwise calling them with
// optfn() or { panic(err) } will cause a panic: // optfn() or { panic(err) } will cause a panic:
@ -208,11 +208,11 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
if g.pref.printfn_list.len > 0 && g.last_fn_c_name in g.pref.printfn_list { if g.pref.printfn_list.len > 0 && g.last_fn_c_name in g.pref.printfn_list {
println(g.out.after(fn_start_pos)) println(g.out.after(fn_start_pos))
} }
for attr in it.attrs { for attr in node.attrs {
if attr.name == 'export' { if attr.name == 'export' {
g.writeln('// export alias: $attr.arg -> $name') g.writeln('// export alias: $attr.arg -> $name')
export_alias := '$type_name ${attr.arg}($arg_str)' export_alias := '$type_name ${attr.arg}($arg_str)'
g.definitions.writeln('VV_EXPORTED_SYMBOL $export_alias; // exported fn $it.name') g.definitions.writeln('VV_EXPORTED_SYMBOL $export_alias; // exported fn $node.name')
g.writeln('$export_alias {') g.writeln('$export_alias {')
g.write('\treturn ${name}(') g.write('\treturn ${name}(')
g.write(fargs.join(', ')) g.write(fargs.join(', '))