checker, cgen: c2v variadic fixes
parent
10fb16e00b
commit
8b0e843cb8
|
@ -213,8 +213,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c.pref.translated || c.file.is_translated) && node.is_variadic
|
//&& node.params.len == 1 && param.typ.is_ptr() {
|
||||||
&& node.params.len == 1 && param.typ.is_ptr() {
|
if (c.pref.translated || c.file.is_translated) && node.is_variadic && param.typ.is_ptr() {
|
||||||
// TODO c2v hack to fix `(const char *s, ...)`
|
// TODO c2v hack to fix `(const char *s, ...)`
|
||||||
param.typ = ast.int_type.ref()
|
param.typ = ast.int_type.ref()
|
||||||
}
|
}
|
||||||
|
|
|
@ -533,33 +533,37 @@ fn (mut g Gen) write_defer_stmts_when_needed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) fn_decl_params(params []ast.Param, scope &ast.Scope, is_variadic bool) ([]string, []string, []bool) {
|
fn (mut g Gen) fn_decl_params(params []ast.Param, scope &ast.Scope, is_variadic bool) ([]string, []string, []bool) {
|
||||||
mut fargs := []string{}
|
mut fparams := []string{}
|
||||||
mut fargtypes := []string{}
|
mut fparamtypes := []string{}
|
||||||
mut heap_promoted := []bool{}
|
mut heap_promoted := []bool{}
|
||||||
if params.len == 0 {
|
if params.len == 0 {
|
||||||
// in C, `()` is untyped, unlike `(void)`
|
// in C, `()` is untyped, unlike `(void)`
|
||||||
g.write('void')
|
g.write('void')
|
||||||
}
|
}
|
||||||
for i, arg in params {
|
for i, param in params {
|
||||||
mut caname := if arg.name == '_' { g.new_tmp_declaration_name() } else { c_name(arg.name) }
|
mut caname := if param.name == '_' {
|
||||||
typ := g.unwrap_generic(arg.typ)
|
g.new_tmp_declaration_name()
|
||||||
arg_type_sym := g.table.sym(typ)
|
} else {
|
||||||
mut arg_type_name := g.typ(typ) // util.no_dots(arg_type_sym.name)
|
c_name(param.name)
|
||||||
if arg_type_sym.kind == .function {
|
}
|
||||||
info := arg_type_sym.info as ast.FnType
|
typ := g.unwrap_generic(param.typ)
|
||||||
|
param_type_sym := g.table.sym(typ)
|
||||||
|
mut param_type_name := g.typ(typ) // util.no_dots(param_type_sym.name)
|
||||||
|
if param_type_sym.kind == .function {
|
||||||
|
info := param_type_sym.info as ast.FnType
|
||||||
func := info.func
|
func := info.func
|
||||||
g.write('${g.typ(func.return_type)} (*$caname)(')
|
g.write('${g.typ(func.return_type)} (*$caname)(')
|
||||||
g.definitions.write_string('${g.typ(func.return_type)} (*$caname)(')
|
g.definitions.write_string('${g.typ(func.return_type)} (*$caname)(')
|
||||||
g.fn_decl_params(func.params, voidptr(0), func.is_variadic)
|
g.fn_decl_params(func.params, voidptr(0), func.is_variadic)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
g.definitions.write_string(')')
|
g.definitions.write_string(')')
|
||||||
fargs << caname
|
fparams << caname
|
||||||
fargtypes << arg_type_name
|
fparamtypes << param_type_name
|
||||||
} else {
|
} else {
|
||||||
mut heap_prom := false
|
mut heap_prom := false
|
||||||
if scope != voidptr(0) {
|
if scope != voidptr(0) {
|
||||||
if arg.name != '_' {
|
if param.name != '_' {
|
||||||
if v := scope.find_var(arg.name) {
|
if v := scope.find_var(param.name) {
|
||||||
if !v.is_stack_obj && v.is_auto_heap {
|
if !v.is_stack_obj && v.is_auto_heap {
|
||||||
heap_prom = true
|
heap_prom = true
|
||||||
}
|
}
|
||||||
|
@ -567,17 +571,17 @@ fn (mut g Gen) fn_decl_params(params []ast.Param, scope &ast.Scope, is_variadic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var_name_prefix := if heap_prom { '_v_toheap_' } else { '' }
|
var_name_prefix := if heap_prom { '_v_toheap_' } else { '' }
|
||||||
const_prefix := if arg.typ.is_any_kind_of_pointer() && !arg.is_mut
|
const_prefix := if param.typ.is_any_kind_of_pointer() && !param.is_mut
|
||||||
&& arg.name.starts_with('const_') {
|
&& param.name.starts_with('const_') {
|
||||||
'const '
|
'const '
|
||||||
} else {
|
} else {
|
||||||
''
|
''
|
||||||
}
|
}
|
||||||
s := '$const_prefix$arg_type_name $var_name_prefix$caname'
|
s := '$const_prefix$param_type_name $var_name_prefix$caname'
|
||||||
g.write(s)
|
g.write(s)
|
||||||
g.definitions.write_string(s)
|
g.definitions.write_string(s)
|
||||||
fargs << caname
|
fparams << caname
|
||||||
fargtypes << arg_type_name
|
fparamtypes << param_type_name
|
||||||
heap_promoted << heap_prom
|
heap_promoted << heap_prom
|
||||||
}
|
}
|
||||||
if i < params.len - 1 {
|
if i < params.len - 1 {
|
||||||
|
@ -586,10 +590,10 @@ fn (mut g Gen) fn_decl_params(params []ast.Param, scope &ast.Scope, is_variadic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if g.pref.translated && is_variadic {
|
if g.pref.translated && is_variadic {
|
||||||
g.write(', ...')
|
g.write(', ... ')
|
||||||
g.definitions.write_string(', ...')
|
g.definitions.write_string(', ... ')
|
||||||
}
|
}
|
||||||
return fargs, fargtypes, heap_promoted
|
return fparams, fparamtypes, heap_promoted
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) get_anon_fn_type_name(mut node ast.AnonFn, var_name string) string {
|
fn (mut g Gen) get_anon_fn_type_name(mut node ast.AnonFn, var_name string) string {
|
||||||
|
@ -1660,15 +1664,27 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
|
||||||
g.expr(args[args.len - 1].expr)
|
g.expr(args[args.len - 1].expr)
|
||||||
} else {
|
} else {
|
||||||
if variadic_count > 0 {
|
if variadic_count > 0 {
|
||||||
noscan := g.check_noscan(arr_info.elem_type)
|
if g.pref.translated || g.file.is_translated {
|
||||||
g.write('new_array_from_c_array${noscan}($variadic_count, $variadic_count, sizeof($elem_type), _MOV(($elem_type[$variadic_count]){')
|
// Handle passing e.g. C string literals to `...` C varargs:
|
||||||
for j in arg_nr .. args.len {
|
// void DEH_snprintf(char *buffer, size_t len, const char *fmt, ...)
|
||||||
g.ref_or_deref_arg(args[j], arr_info.elem_type, node.language)
|
// deh_snprintf(buffer, 9, c'STCFN%.3d', j++)
|
||||||
if j < args.len - 1 {
|
for j in arg_nr .. args.len {
|
||||||
g.write(', ')
|
g.expr(args[j].expr)
|
||||||
|
if j < args.len - 1 {
|
||||||
|
g.write(', ')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
noscan := g.check_noscan(arr_info.elem_type)
|
||||||
|
g.write('new_array_from_c_array${noscan}($variadic_count, $variadic_count, sizeof($elem_type), _MOV(($elem_type[$variadic_count]){')
|
||||||
|
for j in arg_nr .. args.len {
|
||||||
|
g.ref_or_deref_arg(args[j], arr_info.elem_type, node.language)
|
||||||
|
if j < args.len - 1 {
|
||||||
|
g.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.write('}))')
|
||||||
}
|
}
|
||||||
g.write('}))')
|
|
||||||
} else {
|
} else {
|
||||||
g.write('__new_array(0, 0, sizeof($elem_type))')
|
g.write('__new_array(0, 0, sizeof($elem_type))')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue