mirror of
https://github.com/vlang/v.git
synced 2025-08-04 02:07:28 -04:00
v.gen.c: support inter-dependent function types (#20638)
This commit is contained in:
parent
d750d1f5a0
commit
a09bd7cff3
@ -1515,11 +1515,7 @@ static inline void __${sym.cname}_pushval(${sym.cname} ch, ${push_arg} val) {
|
|||||||
g.write_alias_typesymbol_declaration(sym)
|
g.write_alias_typesymbol_declaration(sym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for sym in g.table.type_symbols {
|
g.write_sorted_fn_typesymbol_declaration()
|
||||||
if sym.kind == .function && sym.name !in c.builtins {
|
|
||||||
g.write_fn_typesymbol_declaration(sym)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Generating interfaces after all the common types have been defined
|
// Generating interfaces after all the common types have been defined
|
||||||
// to prevent generating interface struct before definition of field types
|
// to prevent generating interface struct before definition of field types
|
||||||
for sym in g.table.type_symbols {
|
for sym in g.table.type_symbols {
|
||||||
@ -6382,6 +6378,63 @@ fn (mut g Gen) sort_globals_consts() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort functions by dependent arguments and return value
|
||||||
|
// As functions may depend on one another, make sure they are
|
||||||
|
// defined in the correct order: add non dependent ones first.
|
||||||
|
fn (mut g Gen) write_sorted_fn_typesymbol_declaration() {
|
||||||
|
util.timing_start(@METHOD)
|
||||||
|
defer {
|
||||||
|
util.timing_measure(@METHOD)
|
||||||
|
}
|
||||||
|
mut syms := []&ast.TypeSymbol{} // functions to be defined
|
||||||
|
for sym in g.table.type_symbols {
|
||||||
|
if sym.kind == .function && sym.name !in c.builtins {
|
||||||
|
syms << sym
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mut pending := []&ast.TypeSymbol{} // functions with a dependency
|
||||||
|
for {
|
||||||
|
// Add non dependent functions or functions which
|
||||||
|
// dependency has been added.
|
||||||
|
next: for sym in syms {
|
||||||
|
info := sym.info as ast.FnType
|
||||||
|
func := info.func
|
||||||
|
return_sym := g.table.sym(func.return_type)
|
||||||
|
if return_sym in syms {
|
||||||
|
pending << sym
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for param in func.params {
|
||||||
|
param_sym := g.table.sym(param.typ)
|
||||||
|
if param_sym in syms {
|
||||||
|
pending << sym
|
||||||
|
continue next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.write_fn_typesymbol_declaration(sym)
|
||||||
|
}
|
||||||
|
if pending.len == 0 {
|
||||||
|
// All functions were added.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if syms.len == pending.len {
|
||||||
|
// Could not add any function: there is a circular
|
||||||
|
// dependency.
|
||||||
|
mut deps := []string{}
|
||||||
|
for sym in pending {
|
||||||
|
deps << sym.name
|
||||||
|
}
|
||||||
|
verror(
|
||||||
|
'cgen.write_sorted_fn_typesymbol_declaration(): the following functions form a dependency cycle:\n' +
|
||||||
|
deps.join(','))
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
// Swap the to-be-processed and the dependent functions.
|
||||||
|
syms, pending = pending, syms[..0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// sort structs by dependent fields
|
// sort structs by dependent fields
|
||||||
fn (mut g Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
|
fn (mut g Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
|
||||||
util.timing_start(@METHOD)
|
util.timing_start(@METHOD)
|
||||||
|
4
vlib/v/gen/c/testdata/func_type_dependency.c.must_have
vendored
Normal file
4
vlib/v/gen/c/testdata/func_type_dependency.c.must_have
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
typedef void (*gdi__Function_ptr)();
|
||||||
|
typedef void (*gdi__Function_ptr2)();
|
||||||
|
typedef gdi__Function_ptr* (*gdi__Get_proc_address)(i8*);
|
||||||
|
typedef void (*gdi__Set_proc_address)(gdi__Function_ptr2*);
|
8
vlib/v/gen/c/testdata/func_type_dependency.vv
vendored
Normal file
8
vlib/v/gen/c/testdata/func_type_dependency.vv
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// vtest vflags: -shared
|
||||||
|
module gdi
|
||||||
|
|
||||||
|
pub type Get_proc_address = fn(&i8) &Function_ptr
|
||||||
|
pub type Set_proc_address = fn(&Function_ptr2)
|
||||||
|
|
||||||
|
pub type Function_ptr = fn ()
|
||||||
|
pub type Function_ptr2 = fn ()
|
Loading…
x
Reference in New Issue
Block a user