diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index dd7e6573dc..cf6b34bf22 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -362,6 +362,7 @@ pub fn (mut g Gen) init() { g.cheaders.writeln('#include ') } g.write_builtin_types() + g.write_multi_return_typedefs() g.write_typedef_types() g.write_typeof_functions() if g.pref.build_mode != .build_module { @@ -369,7 +370,7 @@ pub fn (mut g Gen) init() { g.write_str_fn_definitions() } g.write_sorted_types() - g.write_multi_return_types() + g.write_multi_return_structs() g.definitions.writeln('// end of definitions #endif') // g.stringliterals.writeln('') @@ -654,13 +655,8 @@ static inline void __${typ.cname}_pushval($typ.cname ch, $el_stype val) { pub fn (mut g Gen) write_fn_typesymbol_declaration(sym table.TypeSymbol) { info := sym.info as table.FnType func := info.func - mut retsym := g.table.get_type_symbol(func.return_type) - is_multi := retsym.kind == .multi_return is_fn_sig := func.name == '' not_anon := !info.is_anon - if is_multi { - g.write_multi_return_type_declaration(mut retsym) - } if !info.has_decl && (not_anon || is_fn_sig) { fn_name := sym.cname g.type_definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(') @@ -674,30 +670,30 @@ pub fn (mut g Gen) write_fn_typesymbol_declaration(sym table.TypeSymbol) { } } -pub fn (mut g Gen) write_multi_return_type_declaration(mut sym table.TypeSymbol) { - if sym.is_written { - return - } - info := sym.info as table.MultiReturn - g.type_definitions.writeln('typedef struct {') - // TODO copy pasta StructDecl - // for field in struct_info.fields { - for i, mr_typ in info.types { - type_name := g.typ(mr_typ) - g.type_definitions.writeln('\t$type_name arg$i;') - } - g.type_definitions.writeln('} $sym.cname;\n') - // g.typedefs.writeln('typedef struct $name $name;') - sym.is_written = true -} - -pub fn (mut g Gen) write_multi_return_types() { - g.type_definitions.writeln('\n// BEGIN_multi_return_structs') - for idx in 0 .. g.table.types.len { - if g.table.types[idx].kind != .multi_return { +pub fn (mut g Gen) write_multi_return_typedefs() { + g.type_definitions.writeln('\n// BEGIN_multi_return_typedefs') + for sym in g.table.types { + if sym.kind != .multi_return { continue } - g.write_multi_return_type_declaration(mut g.table.types[idx]) + g.type_definitions.writeln('typedef struct $sym.cname $sym.cname;') + } + g.type_definitions.writeln('// END_multi_return_typedefs\n') +} + +pub fn (mut g Gen) write_multi_return_structs() { + g.type_definitions.writeln('\n// BEGIN_multi_return_structs') + for sym in g.table.types { + if sym.kind != .multi_return { + continue + } + info := sym.info as table.MultiReturn + g.type_definitions.writeln('struct $sym.cname {') + for i, mr_typ in info.types { + type_name := g.typ(mr_typ) + g.type_definitions.writeln('\t$type_name arg$i;') + } + g.type_definitions.writeln('};\n') } g.type_definitions.writeln('// END_multi_return_structs\n') } diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index ae5675e1f4..984b1841e7 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -42,7 +42,6 @@ pub mut: methods []Fn mod string is_public bool - is_written bool // set to true, when the backend definition for a symbol had been written, to avoid duplicates language Language } @@ -183,7 +182,6 @@ pub fn (ts TypeSymbol) debug() []string { res << 'info: $ts.info' res << 'kind: $ts.kind' res << 'is_public: $ts.is_public' - res << 'is_written: $ts.is_written' res << 'language: $ts.language' res << 'methods ($ts.methods.len): ' + ts.methods.map(it.str()).join(', ') return res diff --git a/vlib/v/tests/str_gen_test.v b/vlib/v/tests/str_gen_test.v index eac0ad261a..6444c9940a 100644 --- a/vlib/v/tests/str_gen_test.v +++ b/vlib/v/tests/str_gen_test.v @@ -390,5 +390,15 @@ fn test_multi_return() { value: 'one' }, Two{ value: 'two' +})" + anon_a := fn() (One, Two) { + one := One{} + two := Two{} + return one, two + } + assert '$anon_a()' == "(One{ + value: 'one' +}, Two{ + value: 'two' })" }