mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: pass sum type values automatically by reference too, when functions require that (#17476)
This commit is contained in:
parent
904f984367
commit
5e2ff246c8
|
@ -2289,6 +2289,7 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) {
|
||||||
[inline]
|
[inline]
|
||||||
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang ast.Language) {
|
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang ast.Language) {
|
||||||
arg_typ := g.unwrap_generic(arg.typ)
|
arg_typ := g.unwrap_generic(arg.typ)
|
||||||
|
arg_sym := g.table.sym(arg_typ)
|
||||||
exp_is_ptr := expected_type.is_ptr() || expected_type.idx() in ast.pointer_type_idxs
|
exp_is_ptr := expected_type.is_ptr() || expected_type.idx() in ast.pointer_type_idxs
|
||||||
arg_is_ptr := arg_typ.is_ptr() || arg_typ.idx() in ast.pointer_type_idxs
|
arg_is_ptr := arg_typ.is_ptr() || arg_typ.idx() in ast.pointer_type_idxs
|
||||||
if expected_type == 0 {
|
if expected_type == 0 {
|
||||||
|
@ -2300,7 +2301,6 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
|
||||||
g.write('&/*mut*/')
|
g.write('&/*mut*/')
|
||||||
} else if exp_is_ptr && !arg_is_ptr {
|
} else if exp_is_ptr && !arg_is_ptr {
|
||||||
if arg.is_mut {
|
if arg.is_mut {
|
||||||
arg_sym := g.table.sym(arg_typ)
|
|
||||||
if exp_sym.kind == .array {
|
if exp_sym.kind == .array {
|
||||||
if (arg.expr is ast.Ident && (arg.expr as ast.Ident).kind == .variable)
|
if (arg.expr is ast.Ident && (arg.expr as ast.Ident).kind == .variable)
|
||||||
|| arg.expr is ast.SelectorExpr {
|
|| arg.expr is ast.SelectorExpr {
|
||||||
|
@ -2353,6 +2353,19 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
|
||||||
g.write('ADDR(${g.typ(atype)}/*qq*/, ')
|
g.write('ADDR(${g.typ(atype)}/*qq*/, ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if arg_sym.kind == .sum_type && exp_sym.kind == .sum_type {
|
||||||
|
// Automatically passing sum types by reference if the argument expects it,
|
||||||
|
// not only the argument is mutable.
|
||||||
|
if arg.expr is ast.SelectorExpr {
|
||||||
|
g.write('&/*sum*/')
|
||||||
|
g.expr(arg.expr)
|
||||||
|
return
|
||||||
|
} else if arg.expr is ast.CastExpr {
|
||||||
|
g.write('ADDR(${g.typ(expected_deref_type)}/*sum*/, ')
|
||||||
|
g.expr_with_cast(arg.expr, arg_typ, expected_type)
|
||||||
|
g.write(')')
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if arg_typ.has_flag(.shared_f) && !expected_type.has_flag(.shared_f) {
|
} else if arg_typ.has_flag(.shared_f) && !expected_type.has_flag(.shared_f) {
|
||||||
|
|
20
vlib/v/gen/c/testdata/sumtype_pass_by_reference.out
vendored
Normal file
20
vlib/v/gen/c/testdata/sumtype_pass_by_reference.out
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
&Expr(ParExpr{
|
||||||
|
expr: Expr(InfixExpr{
|
||||||
|
left: unknown sum type value
|
||||||
|
right: unknown sum type value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
&Expr(ParExpr{
|
||||||
|
expr: Expr(InfixExpr{
|
||||||
|
left: unknown sum type value
|
||||||
|
right: unknown sum type value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
&Expr(InfixExpr{
|
||||||
|
left: unknown sum type value
|
||||||
|
right: unknown sum type value
|
||||||
|
})
|
||||||
|
&Expr(InfixExpr{
|
||||||
|
left: unknown sum type value
|
||||||
|
right: unknown sum type value
|
||||||
|
})
|
27
vlib/v/gen/c/testdata/sumtype_pass_by_reference.vv
vendored
Normal file
27
vlib/v/gen/c/testdata/sumtype_pass_by_reference.vv
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
struct ParExpr {
|
||||||
|
expr Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InfixExpr {
|
||||||
|
left Expr
|
||||||
|
right Expr
|
||||||
|
}
|
||||||
|
|
||||||
|
type Expr = InfixExpr | ParExpr
|
||||||
|
|
||||||
|
fn print_expr(expr &Expr) {
|
||||||
|
println(expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
par := ParExpr{
|
||||||
|
expr: InfixExpr{}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_expr(par)
|
||||||
|
print_expr(Expr(par))
|
||||||
|
print_expr(par.expr)
|
||||||
|
print_expr(&par.expr)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user