cgen: fix autogen free method for struct with shared field (#13469)
parent
89e9f8a00c
commit
e23db2f9b7
|
@ -5,7 +5,8 @@ module c
|
||||||
import v.ast
|
import v.ast
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
fn (mut g Gen) gen_free_method_for_type(typ ast.Type) string {
|
fn (mut g Gen) get_free_method(typ ast.Type) string {
|
||||||
|
g.autofree_methods[typ] = true
|
||||||
styp := g.typ(typ).replace('*', '')
|
styp := g.typ(typ).replace('*', '')
|
||||||
mut sym := g.table.sym(g.unwrap_generic(typ))
|
mut sym := g.table.sym(g.unwrap_generic(typ))
|
||||||
mut fn_name := styp_to_free_fn_name(styp)
|
mut fn_name := styp_to_free_fn_name(styp)
|
||||||
|
@ -15,6 +16,32 @@ fn (mut g Gen) gen_free_method_for_type(typ ast.Type) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sym.has_method_with_generic_parent('free') {
|
||||||
|
return fn_name
|
||||||
|
}
|
||||||
|
return fn_name
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_free_methods() {
|
||||||
|
for typ, _ in g.autofree_methods {
|
||||||
|
g.gen_free_method(typ)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_free_method(typ ast.Type) string {
|
||||||
|
styp := g.typ(typ).replace('*', '')
|
||||||
|
mut sym := g.table.sym(g.unwrap_generic(typ))
|
||||||
|
mut fn_name := styp_to_free_fn_name(styp)
|
||||||
|
if typ in g.generated_free_methods {
|
||||||
|
return fn_name
|
||||||
|
}
|
||||||
|
g.generated_free_methods[typ] = true
|
||||||
|
if mut sym.info is ast.Alias {
|
||||||
|
if sym.info.is_import {
|
||||||
|
sym = g.table.sym(sym.info.parent_type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if sym.has_method_with_generic_parent('free') {
|
if sym.has_method_with_generic_parent('free') {
|
||||||
return fn_name
|
return fn_name
|
||||||
}
|
}
|
||||||
|
@ -50,13 +77,21 @@ fn (mut g Gen) gen_free_for_struct(info ast.Struct, styp string, fn_name string)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mut field_styp := g.typ(field.typ).replace('*', '')
|
mut field_styp := g.typ(field.typ).replace('*', '')
|
||||||
|
is_shared := field_styp.starts_with('__shared')
|
||||||
|
if is_shared {
|
||||||
|
field_styp = field_styp.all_after('__shared__')
|
||||||
|
}
|
||||||
field_styp_fn_name := if sym.has_method('free') {
|
field_styp_fn_name := if sym.has_method('free') {
|
||||||
'${field_styp}_free'
|
'${field_styp}_free'
|
||||||
} else {
|
} else {
|
||||||
g.gen_free_method_for_type(field.typ)
|
g.gen_free_method(field.typ)
|
||||||
}
|
}
|
||||||
|
if is_shared {
|
||||||
|
fn_builder.writeln('\t${field_styp_fn_name}(&(it->$field.name->val));')
|
||||||
|
} else {
|
||||||
fn_builder.writeln('\t${field_styp_fn_name}(&(it->$field.name));')
|
fn_builder.writeln('\t${field_styp_fn_name}(&(it->$field.name));')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fn_builder.writeln('}')
|
fn_builder.writeln('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +111,7 @@ fn (mut g Gen) gen_free_for_array(info ast.Array, styp string, fn_name string) {
|
||||||
elem_styp_fn_name := if sym.has_method('free') {
|
elem_styp_fn_name := if sym.has_method('free') {
|
||||||
'${elem_styp}_free'
|
'${elem_styp}_free'
|
||||||
} else {
|
} else {
|
||||||
g.gen_free_method_for_type(info.elem_type)
|
g.gen_free_method(info.elem_type)
|
||||||
}
|
}
|
||||||
fn_builder.writeln('\t\t${elem_styp_fn_name}(&((($elem_styp*)it->data)[i]));')
|
fn_builder.writeln('\t\t${elem_styp_fn_name}(&((($elem_styp*)it->data)[i]));')
|
||||||
fn_builder.writeln('\t}')
|
fn_builder.writeln('\t}')
|
||||||
|
|
|
@ -200,6 +200,8 @@ mut:
|
||||||
cur_concrete_types []ast.Type // do not use table.cur_concrete_types because table is global, so should not be accessed by different threads
|
cur_concrete_types []ast.Type // do not use table.cur_concrete_types because table is global, so should not be accessed by different threads
|
||||||
cur_fn &ast.FnDecl = 0 // same here
|
cur_fn &ast.FnDecl = 0 // same here
|
||||||
cur_lock ast.LockExpr
|
cur_lock ast.LockExpr
|
||||||
|
autofree_methods map[int]bool
|
||||||
|
generated_free_methods map[int]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
||||||
|
@ -346,6 +348,9 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
||||||
global_g.json_types << g.json_types
|
global_g.json_types << g.json_types
|
||||||
global_g.hotcode_fn_names << g.hotcode_fn_names
|
global_g.hotcode_fn_names << g.hotcode_fn_names
|
||||||
unsafe { g.free_builders() }
|
unsafe { g.free_builders() }
|
||||||
|
for k, v in g.autofree_methods {
|
||||||
|
global_g.autofree_methods[k] = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for file in files {
|
for file in files {
|
||||||
|
@ -374,6 +379,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
||||||
global_g.gen_array_contains_methods()
|
global_g.gen_array_contains_methods()
|
||||||
global_g.gen_array_index_methods()
|
global_g.gen_array_index_methods()
|
||||||
global_g.gen_equality_fns()
|
global_g.gen_equality_fns()
|
||||||
|
global_g.gen_free_methods()
|
||||||
global_g.timers.show('cgen unification')
|
global_g.timers.show('cgen unification')
|
||||||
|
|
||||||
mut g := global_g
|
mut g := global_g
|
||||||
|
|
|
@ -911,7 +911,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
if rec_type.has_flag(.shared_f) {
|
if rec_type.has_flag(.shared_f) {
|
||||||
rec_type = rec_type.clear_flag(.shared_f).set_nr_muls(0)
|
rec_type = rec_type.clear_flag(.shared_f).set_nr_muls(0)
|
||||||
}
|
}
|
||||||
g.gen_free_method_for_type(rec_type)
|
g.get_free_method(rec_type)
|
||||||
}
|
}
|
||||||
mut has_cast := false
|
mut has_cast := false
|
||||||
if left_sym.kind == .map && node.name in ['clone', 'move'] {
|
if left_sym.kind == .map && node.name in ['clone', 'move'] {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
struct Info {
|
struct Info {
|
||||||
name string
|
name string
|
||||||
notes []string
|
notes shared []string
|
||||||
maps map[int]int
|
maps map[int]int
|
||||||
info []SubInfo
|
info []SubInfo
|
||||||
}
|
}
|
||||||
|
@ -15,3 +15,9 @@ fn test_autogen_free() {
|
||||||
info.free()
|
info.free()
|
||||||
assert true
|
assert true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_multiple_autogen_free() {
|
||||||
|
info := &Info{}
|
||||||
|
info.free()
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue