1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: minor cleanup of gen_fn_decl (#8474)

This commit is contained in:
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

View File

@ -7,18 +7,18 @@ import v.ast
import v.table
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
// as it's only informative, comment it for now
// g.gen_attrs(it.attrs)
if it.language == .c {
// || it.no_body {
if node.language == .c {
// || node.no_body {
return
}
g.returned_var_name = ''
//
old_g_autofree := g.is_autofree
if it.is_manualfree {
if node.is_manualfree {
g.is_autofree = false
}
defer {
@ -26,49 +26,49 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
}
//
// 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
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 {
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.gen_fn_decl(it, skip)
g.gen_fn_decl(node, skip)
}
g.cur_generic_types = []
return
}
g.cur_fn = it
g.cur_fn = node
fn_start_pos := g.out.len
g.write_v_source_line_info(it.pos)
msvc_attrs := g.write_fn_attrs(it.attrs)
g.write_v_source_line_info(node.pos)
msvc_attrs := g.write_fn_attrs(node.attrs)
// Live
is_livefn := it.attrs.contains('live')
is_livefn := node.attrs.contains('live')
is_livemain := g.pref.is_livemain && is_livefn
is_liveshared := g.pref.is_liveshared && is_livefn
is_livemode := g.pref.is_livemain || g.pref.is_liveshared
is_live_wrap := 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 ['+', '-', '*', '/', '%', '<', '>', '==', '!=', '<=', '>='] {
name = util.replace_op(name)
}
if it.is_method {
name = g.cc_type2(it.receiver.typ) + '_' + name
// name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
if node.is_method {
name = g.cc_type2(node.receiver.typ) + '_' + 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)
} else {
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 {
// foo<T>() => foo_T_int(), foo_T_string() etc
// 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}(')
}
} 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
// binaries
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.write(fn_header)
}
for param in it.params {
for param in node.params {
if param.is_mut {
g.fn_mut_arg_names << param.name
}
}
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)
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 {
// Just a function header. Builtin function bodies are defined in builtin.o
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).
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
prev_defer_stmts := g.defer_stmts
g.defer_stmts = []
g.stmts(it.stmts)
g.stmts(node.stmts)
// clear g.fn_mut_arg_names
if g.fn_mut_arg_names.len > 0 {
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()
}
if it.is_anon {
if node.is_anon {
g.defer_stmts = prev_defer_stmts
} else {
g.defer_stmts = []
}
if it.return_type != table.void_type && it.stmts.len > 0 && it.stmts.last() !is ast.Return {
default_expr := g.type_default(it.return_type)
if node.return_type != table.void_type && node.stmts.len > 0 && node.stmts.last() !is ast.Return {
default_expr := g.type_default(node.return_type)
// TODO: perf?
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 `?,
// should have .ok = true set, otherwise calling them with
// 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 {
println(g.out.after(fn_start_pos))
}
for attr in it.attrs {
for attr in node.attrs {
if attr.name == 'export' {
g.writeln('// export alias: $attr.arg -> $name')
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.write('\treturn ${name}(')
g.write(fargs.join(', '))