cgen: fix codegen for aliases of fixed arrays of structs (fix #13037) (#13049)

pull/13058/head
yuyi 2022-01-06 17:54:22 +08:00 committed by GitHub
parent fca699a439
commit fb66ec7cfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 36 deletions

View File

@ -59,7 +59,7 @@ fn (mut g Gen) gen_sumtype_equality_fn(left_type ast.Type) string {
g.generated_eq_fns << left_type
info := left.sym.sumtype_info()
g.type_definitions.writeln('static bool ${ptr_styp}_sumtype_eq($ptr_styp a, $ptr_styp b); // auto')
g.definitions.writeln('static bool ${ptr_styp}_sumtype_eq($ptr_styp a, $ptr_styp b); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static bool ${ptr_styp}_sumtype_eq($ptr_styp a, $ptr_styp b) {')
@ -110,7 +110,7 @@ fn (mut g Gen) gen_struct_equality_fn(left_type ast.Type) string {
}
g.generated_eq_fns << left_type
info := left.sym.struct_info()
g.type_definitions.writeln('static bool ${fn_name}_struct_eq($ptr_styp a, $ptr_styp b); // auto')
g.definitions.writeln('static bool ${fn_name}_struct_eq($ptr_styp a, $ptr_styp b); // auto')
mut fn_builder := strings.new_builder(512)
defer {
@ -178,7 +178,7 @@ fn (mut g Gen) gen_alias_equality_fn(left_type ast.Type) string {
}
g.generated_eq_fns << left_type
info := left.sym.info as ast.Alias
g.type_definitions.writeln('static bool ${ptr_styp}_alias_eq($ptr_styp a, $ptr_styp b); // auto')
g.definitions.writeln('static bool ${ptr_styp}_alias_eq($ptr_styp a, $ptr_styp b); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static bool ${ptr_styp}_alias_eq($ptr_styp a, $ptr_styp b) {')
@ -222,7 +222,7 @@ fn (mut g Gen) gen_array_equality_fn(left_type ast.Type) string {
g.generated_eq_fns << left_type
elem := g.unwrap(left.sym.array_info().elem_type)
ptr_elem_styp := g.typ(elem.typ)
g.type_definitions.writeln('static bool ${ptr_styp}_arr_eq($ptr_styp a, $ptr_styp b); // auto')
g.definitions.writeln('static bool ${ptr_styp}_arr_eq($ptr_styp a, $ptr_styp b); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static bool ${ptr_styp}_arr_eq($ptr_styp a, $ptr_styp b) {')
@ -278,7 +278,7 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left_type ast.Type) string {
elem_info := left.sym.array_fixed_info()
elem := g.unwrap(elem_info.elem_type)
size := elem_info.size
g.type_definitions.writeln('static bool ${ptr_styp}_arr_eq($ptr_styp a, $ptr_styp b); // auto')
g.definitions.writeln('static bool ${ptr_styp}_arr_eq($ptr_styp a, $ptr_styp b); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static bool ${ptr_styp}_arr_eq($ptr_styp a, $ptr_styp b) {')
@ -330,7 +330,7 @@ fn (mut g Gen) gen_map_equality_fn(left_type ast.Type) string {
g.generated_eq_fns << left_type
value := g.unwrap(left.sym.map_info().value_type)
ptr_value_styp := g.typ(value.typ)
g.type_definitions.writeln('static bool ${ptr_styp}_map_eq($ptr_styp a, $ptr_styp b); // auto')
g.definitions.writeln('static bool ${ptr_styp}_map_eq($ptr_styp a, $ptr_styp b); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static bool ${ptr_styp}_map_eq($ptr_styp a, $ptr_styp b) {')
@ -415,7 +415,7 @@ fn (mut g Gen) gen_interface_equality_fn(left_type ast.Type) string {
}
g.generated_eq_fns << left_type
info := left.sym.info
g.type_definitions.writeln('static bool ${ptr_styp}_interface_eq($ptr_styp a, $ptr_styp b); // auto')
g.definitions.writeln('static bool ${ptr_styp}_interface_eq($ptr_styp a, $ptr_styp b); // auto')
mut fn_builder := strings.new_builder(512)
defer {

View File

@ -37,7 +37,7 @@ fn (mut g Gen) gen_free_method_for_type(typ ast.Type) string {
}
fn (mut g Gen) gen_free_for_struct(info ast.Struct, styp string, fn_name string) {
g.type_definitions.writeln('void ${fn_name}($styp* it); // auto')
g.definitions.writeln('void ${fn_name}($styp* it); // auto')
mut fn_builder := strings.new_builder(128)
defer {
g.auto_fn_definitions << fn_builder.str()
@ -61,7 +61,7 @@ fn (mut g Gen) gen_free_for_struct(info ast.Struct, styp string, fn_name string)
}
fn (mut g Gen) gen_free_for_array(info ast.Array, styp string, fn_name string) {
g.type_definitions.writeln('void ${fn_name}($styp* it); // auto')
g.definitions.writeln('void ${fn_name}($styp* it); // auto')
mut fn_builder := strings.new_builder(128)
defer {
g.auto_fn_definitions << fn_builder.str()
@ -86,7 +86,7 @@ fn (mut g Gen) gen_free_for_array(info ast.Array, styp string, fn_name string) {
}
fn (mut g Gen) gen_free_for_map(info ast.Map, styp string, fn_name string) {
g.type_definitions.writeln('void ${fn_name}($styp* it); // auto')
g.definitions.writeln('void ${fn_name}($styp* it); // auto')
mut fn_builder := strings.new_builder(128)
defer {
g.auto_fn_definitions << fn_builder.str()

View File

@ -107,7 +107,7 @@ fn (mut g Gen) gen_str_default(sym ast.TypeSymbol, styp string, str_fn_name stri
} else {
verror('could not generate string method for type `$styp`')
}
g.type_definitions.writeln('string ${str_fn_name}($styp it); // auto')
g.definitions.writeln('string ${str_fn_name}($styp it); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) {')
if convertor == 'bool' {
g.auto_str_funcs.writeln('\tstring tmp1 = string__plus(_SLIT("${styp}("), ($convertor)it ? _SLIT("true") : _SLIT("false"));')
@ -234,9 +234,9 @@ fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string)
sym_has_str_method, _, _ := sym.str_method_info()
parent_str_fn_name := g.get_str_fn(parent_type)
g.type_definitions.writeln('string ${str_fn_name}($styp it); // auto')
g.definitions.writeln('string ${str_fn_name}($styp it); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}($styp it) { return indent_${str_fn_name}(it, 0); }')
g.type_definitions.writeln('string indent_${str_fn_name}($styp it, int indent_count); // auto')
g.definitions.writeln('string indent_${str_fn_name}($styp it, int indent_count); // auto')
g.auto_str_funcs.writeln('string indent_${str_fn_name}($styp it, int indent_count) {')
g.auto_str_funcs.writeln('\tstring res;')
g.auto_str_funcs.writeln('\tif (it.state == 0) {')
@ -264,9 +264,9 @@ fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string
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.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); }')
g.type_definitions.writeln('static string indent_${str_fn_name}($styp it, int indent_count); // auto')
g.definitions.writeln('static string indent_${str_fn_name}($styp it, int indent_count); // auto')
g.auto_str_funcs.writeln('static string indent_${str_fn_name}($styp it, int indent_count) {')
g.auto_str_funcs.writeln('\tstring indents = string_repeat(_SLIT(" "), indent_count);')
g.auto_str_funcs.writeln('\tstring tmp_ds = ${parent_str_fn_name}(it);')
@ -285,7 +285,7 @@ fn (mut g Gen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str_f
$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')
g.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) {')
fn_builder.writeln('\tstrings__Builder sb = strings__new_builder($info.types.len * 10);')
@ -333,7 +333,7 @@ fn (mut g Gen) gen_str_for_enum(info ast.Enum, styp string, str_fn_name string)
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.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 */')
// Enums tagged with `[flag]` are special in that they can be a combination of enum values
if info.is_flag {
@ -368,9 +368,9 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_nam
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.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); }')
g.type_definitions.writeln('static string indent_${str_fn_name}($styp x, int indent_count); // auto')
g.definitions.writeln('static string indent_${str_fn_name}($styp x, int indent_count); // auto')
mut fn_builder := strings.new_builder(512)
mut clean_interface_v_type_name := styp.replace('__', '.')
if styp.ends_with('*') {
@ -429,9 +429,9 @@ fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, str_fn_
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.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); }')
g.type_definitions.writeln('static string indent_${str_fn_name}($styp x, int indent_count); // auto')
g.definitions.writeln('static string indent_${str_fn_name}($styp x, int indent_count); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static string indent_${str_fn_name}($styp x, int indent_count) {')
mut clean_sum_type_v_type_name := ''
@ -521,7 +521,7 @@ fn (mut g Gen) gen_str_for_fn_type(info ast.FnType, styp string, str_fn_name str
$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.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)}");}')
}
@ -530,7 +530,7 @@ fn (mut g Gen) gen_str_for_chan(info ast.Chan, styp string, str_fn_name string)
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.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")); }')
}
@ -539,7 +539,7 @@ fn (mut g Gen) gen_str_for_thread(info ast.Thread, styp string, str_fn_name stri
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.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)");}')
}
@ -578,9 +578,9 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string
elem_str_fn_name = elem_str_fn_name + '_escaped'
}
g.type_definitions.writeln('static string ${str_fn_name}($styp a); // auto')
g.definitions.writeln('static string ${str_fn_name}($styp a); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp a) { return indent_${str_fn_name}(a, 0);}')
g.type_definitions.writeln('static string indent_${str_fn_name}($styp a, int indent_count); // auto')
g.definitions.writeln('static string indent_${str_fn_name}($styp a, int indent_count); // auto')
g.auto_str_funcs.writeln('static string indent_${str_fn_name}($styp a, int indent_count) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(a.len * 10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _SLIT("["));')
@ -650,9 +650,9 @@ fn (mut g Gen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_fn_
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
elem_str_fn_name := g.get_str_fn(typ)
g.type_definitions.writeln('static string ${str_fn_name}($styp a); // auto')
g.definitions.writeln('static string ${str_fn_name}($styp a); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp a) { return indent_${str_fn_name}(a, 0);}')
g.type_definitions.writeln('static string indent_${str_fn_name}($styp a, int indent_count); // auto')
g.definitions.writeln('static string indent_${str_fn_name}($styp a, int indent_count); // auto')
g.auto_str_funcs.writeln('static string indent_${str_fn_name}($styp a, int indent_count) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder($info.size * 10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _SLIT("["));')
@ -727,9 +727,9 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
g.get_str_fn(val_typ)
}
g.type_definitions.writeln('static string ${str_fn_name}($styp m); // auto')
g.definitions.writeln('static string ${str_fn_name}($styp m); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp m) { return indent_${str_fn_name}(m, 0);}')
g.type_definitions.writeln('static string indent_${str_fn_name}($styp m, int indent_count); // auto')
g.definitions.writeln('static string indent_${str_fn_name}($styp m, int indent_count); // auto')
g.auto_str_funcs.writeln('static string indent_${str_fn_name}($styp m, int indent_count) { /* gen_str_for_map */')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(m.key_values.len*10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _SLIT("{"));')
@ -827,9 +827,9 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
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.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);}')
g.type_definitions.writeln('static string indent_${str_fn_name}($styp it, int indent_count); // auto')
g.definitions.writeln('static string indent_${str_fn_name}($styp it, int indent_count); // auto')
mut fn_builder := strings.new_builder(512)
defer {
g.auto_fn_definitions << fn_builder.str()

View File

@ -53,6 +53,7 @@ mut:
enum_typedefs strings.Builder // enum types
definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file)
type_definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file)
alias_definitions strings.Builder // alias fixed array of non-builtin
hotcode_definitions strings.Builder // -live declarations & functions
channel_definitions strings.Builder // channel related code
comptime_definitions strings.Builder // custom defines, given by -d/-define flags on the CLI
@ -65,6 +66,7 @@ mut:
gowrappers strings.Builder // all go callsite wrappers
stringliterals strings.Builder // all string literals (they depend on tos3() beeing defined
auto_str_funcs strings.Builder // function bodies of all auto generated _str funcs
dump_funcs strings.Builder // function bodies of all auto generated _str funcs
pcs_declarations strings.Builder // -prof profile counter declarations for each function
embedded_data strings.Builder // data to embed in the executable/binary
shared_types strings.Builder // shared/lock types
@ -222,6 +224,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
typedefs: strings.new_builder(100)
enum_typedefs: strings.new_builder(100)
type_definitions: strings.new_builder(100)
alias_definitions: strings.new_builder(100)
hotcode_definitions: strings.new_builder(100)
channel_definitions: strings.new_builder(100)
comptime_definitions: strings.new_builder(100)
@ -229,6 +232,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
gowrappers: strings.new_builder(100)
stringliterals: strings.new_builder(100)
auto_str_funcs: strings.new_builder(100)
dump_funcs: strings.new_builder(100)
pcs_declarations: strings.new_builder(100)
embedded_data: strings.new_builder(1000)
options: strings.new_builder(100)
@ -276,10 +280,12 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
global_g.includes.write(g.includes) or { panic(err) }
global_g.typedefs.write(g.typedefs) or { panic(err) }
global_g.type_definitions.write(g.type_definitions) or { panic(err) }
global_g.alias_definitions.write(g.alias_definitions) or { panic(err) }
global_g.definitions.write(g.definitions) or { panic(err) }
global_g.gowrappers.write(g.gowrappers) or { panic(err) }
global_g.stringliterals.write(g.stringliterals) or { panic(err) }
global_g.auto_str_funcs.write(g.auto_str_funcs) or { panic(err) }
global_g.dump_funcs.write(g.auto_str_funcs) or { panic(err) }
global_g.comptime_definitions.write(g.comptime_definitions) or { panic(err) }
global_g.pcs_declarations.write(g.pcs_declarations) or { panic(err) }
global_g.hotcode_definitions.write(g.hotcode_definitions) or { panic(err) }
@ -414,6 +420,8 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
b.write_string(g.enum_typedefs.str())
b.writeln('\n// V type definitions:')
b.write_string(g.type_definitions.str())
b.writeln('\n// V alias definitions:')
b.write_string(g.alias_definitions.str())
b.writeln('\n// V shared types:')
b.write_string(g.shared_types.str())
b.writeln('\n// V Option_xxx definitions:')
@ -458,6 +466,10 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
b.write_string(g.auto_str_funcs.str())
// }
}
if g.dump_funcs.len > 0 {
b.writeln('\n// V dump functions:')
b.write_string(g.dump_funcs.str())
}
if g.auto_fn_definitions.len > 0 {
for fn_def in g.auto_fn_definitions {
b.writeln(fn_def)
@ -498,6 +510,7 @@ fn cgen_process_one_file_cb(p &pool.PoolProcessor, idx int, wid int) &Gen {
includes: strings.new_builder(100)
typedefs: strings.new_builder(100)
type_definitions: strings.new_builder(100)
alias_definitions: strings.new_builder(100)
definitions: strings.new_builder(100)
gowrappers: strings.new_builder(100)
stringliterals: strings.new_builder(100)
@ -549,6 +562,7 @@ pub fn (mut g Gen) free_builders() {
g.includes.free()
g.typedefs.free()
g.type_definitions.free()
g.alias_definitions.free()
g.definitions.free()
g.global_init.free()
g.init.free()
@ -556,6 +570,7 @@ pub fn (mut g Gen) free_builders() {
g.gowrappers.free()
g.stringliterals.free()
g.auto_str_funcs.free()
g.dump_funcs.free()
g.comptime_definitions.free()
g.pcs_declarations.free()
g.hotcode_definitions.free()
@ -1202,6 +1217,7 @@ pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) {
parent := g.table.type_symbols[sym.parent_idx]
is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.`
mut is_typedef := false
mut is_fixed_array_of_non_builtin := false
if parent.info is ast.Struct {
is_typedef = parent.info.is_typedef
}
@ -1215,13 +1231,24 @@ pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) {
} else {
if sym.info is ast.Alias {
parent_styp = g.typ(sym.info.parent_type)
parent_sym := g.table.sym(sym.info.parent_type)
if parent_sym.info is ast.ArrayFixed {
elem_sym := g.table.sym(parent_sym.info.elem_type)
if !elem_sym.is_builtin() {
is_fixed_array_of_non_builtin = true
}
}
}
}
if parent_styp == 'byte' && sym.cname == 'u8' {
// TODO: remove this check; it is here just to fix V rebuilding in -cstrict mode with clang-12
return
}
g.type_definitions.writeln('typedef $parent_styp $sym.cname;')
if is_fixed_array_of_non_builtin {
g.alias_definitions.writeln('typedef $parent_styp $sym.cname;')
} else {
g.type_definitions.writeln('typedef $parent_styp $sym.cname;')
}
}
pub fn (mut g Gen) write_interface_typedef(sym ast.TypeSymbol) {

View File

@ -21,6 +21,7 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) {
fn (mut g Gen) dump_expr_definitions() {
mut dump_typedefs := map[string]bool{}
mut dump_fns := strings.new_builder(100)
mut dump_fn_defs := strings.new_builder(100)
for dump_type, cname in g.table.dumps {
dump_sym := g.table.sym(dump_type)
_, str_method_expects_ptr, _ := dump_sym.str_method_info()
@ -39,6 +40,7 @@ fn (mut g Gen) dump_expr_definitions() {
dump_typedefs['typedef $str_tdef;'] = true
}
dump_fn_name := '_v_dump_expr_$cname' + (if is_ptr { '_ptr' } else { '' })
dump_fn_defs.writeln('$str_dumparg_type ${dump_fn_name}(string fpath, int line, string sexpr, $str_dumparg_type dump_arg);')
if g.writeln_fn_header('$str_dumparg_type ${dump_fn_name}(string fpath, int line, string sexpr, $str_dumparg_type dump_arg)', mut
dump_fns)
{
@ -46,7 +48,12 @@ fn (mut g Gen) dump_expr_definitions() {
}
mut surrounder := util.new_surrounder(3)
surrounder.add('\tstring sline = int_str(line);', '\tstring_free(&sline);')
surrounder.add('\tstring value = ${to_string_fn_name}(${deref}dump_arg);', '\tstring_free(&value);')
if dump_sym.kind == .function {
surrounder.add('\tstring value = ${to_string_fn_name}();', '\tstring_free(&value);')
} else {
surrounder.add('\tstring value = ${to_string_fn_name}(${deref}dump_arg);',
'\tstring_free(&value);')
}
surrounder.add('
strings__Builder sb = strings__new_builder(256);
', '
@ -78,8 +85,8 @@ fn (mut g Gen) dump_expr_definitions() {
for tdef, _ in dump_typedefs {
g.definitions.writeln(tdef)
}
defs := dump_fns.str()
g.definitions.writeln(defs)
g.definitions.writeln(dump_fn_defs.str())
g.dump_funcs.writeln(dump_fns.str())
}
fn (mut g Gen) writeln_fn_header(s string, mut sb strings.Builder) bool {

View File

@ -0,0 +1,9 @@
struct Foo {}
type Bar = [4]Foo
fn test_alias_fixed_array_of_struct() {
bar := Bar([Foo{}, Foo{}, Foo{}, Foo{}]!)
println(bar)
assert '$bar' == 'Bar([Foo{}, Foo{}, Foo{}, Foo{}])'
}