4343 modules map [string ]string // alias -> full module name
4444 fn_ptr_types map [string ]string // fn_ptr:ret|params -> typedef name
4545 fn_decl_param_types map [string ][]types.Type
46+ fn_decl_ret_types map [string ]types.Type // fn decl name (and qualified variants) -> return type
4647 struct_decl_infos map [string ]StructDeclInfo
4748 struct_decl_short_infos map [string ]StructDeclInfo
4849 runtime_inits []string
6061 emitted_optional_types map [string ]bool
6162 emitted_fns map [string ]bool
6263 array_method_cache map [string ]string
64+ param_types_cache map [string ][]types.Type // (name|fallback) -> resolved param types
6365 spawn_wrapper_names map [string ]string
6466 spawn_wrapper_defs []string
6567 parallel_used bool
@@ -104,6 +106,7 @@ pub fn FlatGen.new() FlatGen {
104106 modules: map [string ]string {}
105107 fn_ptr_types: map [string ]string {}
106108 fn_decl_param_types: map [string ][]types.Type{}
109+ fn_decl_ret_types: map [string ]types.Type{}
107110 struct_decl_infos: map [string ]StructDeclInfo{}
108111 struct_decl_short_infos: map [string ]StructDeclInfo{}
109112 cur_param_names: []string {}
@@ -113,6 +116,7 @@ pub fn FlatGen.new() FlatGen {
113116 emitted_optional_types: map [string ]bool {}
114117 emitted_fns: map [string ]bool {}
115118 array_method_cache: map [string ]string {}
119+ param_types_cache: map [string ][]types.Type{}
116120 spawn_wrapper_names: map [string ]string {}
117121 spawn_wrapper_defs: []string {}
118122 str_lits: []string {}
@@ -171,6 +175,7 @@ pub fn (mut g FlatGen) gen_with_used_options(a &flat.FlatAst, used_fns map[strin
171175 g.modules = map [string ]string {}
172176 g.fn_ptr_types = map [string ]string {}
173177 g.fn_decl_param_types = map [string ][]types.Type{}
178+ g.fn_decl_ret_types = map [string ]types.Type{}
174179 g.struct_decl_infos = map [string ]StructDeclInfo{}
175180 g.struct_decl_short_infos = map [string ]StructDeclInfo{}
176181 g.cur_param_names = []string {}
@@ -180,6 +185,7 @@ pub fn (mut g FlatGen) gen_with_used_options(a &flat.FlatAst, used_fns map[strin
180185 g.emitted_optional_types = map [string ]bool {}
181186 g.emitted_fns = map [string ]bool {}
182187 g.array_method_cache = map [string ]string {}
188+ g.param_types_cache = map [string ][]types.Type{}
183189 g.spawn_wrapper_names = map [string ]string {}
184190 g.spawn_wrapper_defs = []string {}
185191 g.parallel_used = false
@@ -284,6 +290,7 @@ fn (mut g FlatGen) collect_gen_info() {
284290 }
285291 ptypes = g.fn_param_types_with_implicit_veb_ctx (node, ptypes)
286292 g.register_fn_decl_param_types (node.value, full_name, ptypes)
293+ g.register_fn_decl_ret_type (node.value, full_name, node.typ)
287294 // Module-level `init()` functions run once at startup. Collect their C
288295 // names so _vinit can invoke them (V semantics).
289296 if node.value == 'init' && ptypes.len == 0 {
@@ -708,6 +715,29 @@ fn (mut g FlatGen) register_fn_decl_param_types(name string, full_name string, p
708715 }
709716}
710717
718+ // register_fn_decl_ret_type indexes a fn decl's return type by its name (and qualified
719+ // variants), so the return type can be looked up in O(1) instead of scanning all AST
720+ // nodes per call (see fn_decl_return_type_for_call_name).
721+ fn (mut g FlatGen) register_fn_decl_ret_type (name string , full_name string , ret_typ string ) {
722+ rt := g.tc.parse_type (ret_typ)
723+ if name ! in g.fn_decl_ret_types {
724+ g.fn_decl_ret_types[name] = rt
725+ }
726+ if g.tc.cur_module.len > 0 && g.tc.cur_module != 'main' && g.tc.cur_module != 'builtin' {
727+ dotted_name := '${g .tc .cur_module }.${name }'
728+ if dotted_name ! in g.fn_decl_ret_types {
729+ g.fn_decl_ret_types[dotted_name] = rt
730+ }
731+ }
732+ if full_name ! in g.fn_decl_ret_types {
733+ g.fn_decl_ret_types[full_name] = rt
734+ }
735+ cname := c_name (name)
736+ if cname != name && cname ! in g.fn_decl_ret_types {
737+ g.fn_decl_ret_types[cname] = rt
738+ }
739+ }
740+
711741// register_struct_decl_info updates register struct decl info state for c.
712742fn (mut g FlatGen) register_struct_decl_info (name string , full_name string , module_name string , node flat.Node) {
713743 info := StructDeclInfo{
0 commit comments