mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parent
f0871b87a4
commit
18f0040388
@ -236,10 +236,6 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c.pref.translated || c.file.is_translated) && node.is_variadic && param.typ.is_ptr() {
|
||||
// TODO c2v hack to fix `(const char *s, ...)`
|
||||
param.typ = ast.int_type.ref()
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.language == .v && node.name.after_char(`.`) == 'init' && !node.is_method
|
||||
@ -1051,25 +1047,32 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
}
|
||||
}
|
||||
if c.pref.translated || c.file.is_translated {
|
||||
// in case of variadic make sure to use array elem type for checks
|
||||
// check_expected_call_arg already does this before checks also.
|
||||
param_type := if param.typ.has_flag(.variadic) {
|
||||
c.table.sym(param.typ).array_info().elem_type
|
||||
} else {
|
||||
param.typ
|
||||
}
|
||||
// TODO duplicated logic in check_types() (check_types.v)
|
||||
// Allow enums to be used as ints and vice versa in translated code
|
||||
if param.typ == ast.int_type && arg_typ_sym.kind == .enum_ {
|
||||
if param_type.idx() in ast.integer_type_idxs && arg_typ_sym.kind == .enum_ {
|
||||
continue
|
||||
}
|
||||
if arg_typ == ast.int_type && param_typ_sym.kind == .enum_ {
|
||||
if arg_typ.idx() in ast.integer_type_idxs && param_typ_sym.kind == .enum_ {
|
||||
continue
|
||||
}
|
||||
|
||||
if (arg_typ == ast.bool_type && param.typ.is_int())
|
||||
|| (arg_typ.is_int() && param.typ == ast.bool_type) {
|
||||
if (arg_typ == ast.bool_type && param_type.is_int())
|
||||
|| (arg_typ.is_int() && param_type == ast.bool_type) {
|
||||
continue
|
||||
}
|
||||
|
||||
// In C unsafe number casts are used all the time (e.g. `char*` where
|
||||
// `int*` is expected etc), so just allow them all.
|
||||
mut param_is_number := c.table.unaliased_type(param.typ).is_number()
|
||||
if param.typ.is_ptr() {
|
||||
param_is_number = param.typ.deref().is_number()
|
||||
mut param_is_number := c.table.unaliased_type(param_type).is_number()
|
||||
if param_type.is_ptr() {
|
||||
param_is_number = param_type.deref().is_number()
|
||||
}
|
||||
mut typ_is_number := c.table.unaliased_type(arg_typ).is_number()
|
||||
if arg_typ.is_ptr() {
|
||||
@ -1079,18 +1082,18 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
continue
|
||||
}
|
||||
// Allow voidptrs for everything
|
||||
if param.typ == ast.voidptr_type_idx || arg_typ == ast.voidptr_type_idx {
|
||||
if param_type == ast.voidptr_type_idx || arg_typ == ast.voidptr_type_idx {
|
||||
continue
|
||||
}
|
||||
if param.typ.is_any_kind_of_pointer() && arg_typ.is_any_kind_of_pointer() {
|
||||
if param_type.is_any_kind_of_pointer() && arg_typ.is_any_kind_of_pointer() {
|
||||
continue
|
||||
}
|
||||
param_typ_sym_ := c.table.sym(c.table.unaliased_type(param.typ))
|
||||
param_typ_sym_ := c.table.sym(c.table.unaliased_type(param_type))
|
||||
arg_typ_sym_ := c.table.sym(c.table.unaliased_type(arg_typ))
|
||||
// Allow `[32]i8` as `&i8` etc
|
||||
if ((arg_typ_sym_.kind == .array_fixed || arg_typ_sym_.kind == .array)
|
||||
&& (param_is_number
|
||||
|| c.table.unaliased_type(param.typ).is_any_kind_of_pointer()))
|
||||
|| c.table.unaliased_type(param_type).is_any_kind_of_pointer()))
|
||||
|| ((param_typ_sym_.kind == .array_fixed || param_typ_sym_.kind == .array)
|
||||
&& (typ_is_number || c.table.unaliased_type(arg_typ).is_any_kind_of_pointer())) {
|
||||
continue
|
||||
@ -1107,7 +1110,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
}
|
||||
}
|
||||
// Allow `int` as `&i8`
|
||||
if param.typ.is_any_kind_of_pointer() && typ_is_number {
|
||||
if param_type.is_any_kind_of_pointer() && typ_is_number {
|
||||
continue
|
||||
}
|
||||
// Allow `&i8` as `int`
|
||||
|
@ -941,11 +941,9 @@ fn (mut g Gen) base_type(_t ast.Type) string {
|
||||
if t.has_flag(.shared_f) {
|
||||
styp = g.find_or_register_shared(t, styp)
|
||||
}
|
||||
if !t.has_flag(.variadic) {
|
||||
nr_muls := g.unwrap_generic(t).nr_muls()
|
||||
if nr_muls > 0 {
|
||||
styp += strings.repeat(`*`, nr_muls)
|
||||
}
|
||||
nr_muls := g.unwrap_generic(t).nr_muls()
|
||||
if nr_muls > 0 {
|
||||
styp += strings.repeat(`*`, nr_muls)
|
||||
}
|
||||
return styp
|
||||
}
|
||||
|
@ -559,7 +559,10 @@ fn (mut g Gen) fn_decl_params(params []ast.Param, scope &ast.Scope, is_variadic
|
||||
} else {
|
||||
c_name(param.name)
|
||||
}
|
||||
typ := g.unwrap_generic(param.typ)
|
||||
mut typ := g.unwrap_generic(param.typ)
|
||||
if g.pref.translated && g.file.is_translated && param.typ.has_flag(.variadic) {
|
||||
typ = g.table.sym(g.unwrap_generic(param.typ)).array_info().elem_type.set_flag(.variadic)
|
||||
}
|
||||
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 {
|
||||
|
@ -967,7 +967,8 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
|
||||
}
|
||||
}
|
||||
if is_variadic {
|
||||
typ = ast.new_type(p.table.find_or_register_array(typ)).derive(typ).set_flag(.variadic)
|
||||
// derive flags, however nr_muls only needs to be set on the array elem type, so clear it on the arg type
|
||||
typ = ast.new_type(p.table.find_or_register_array(typ)).derive(typ).set_nr_muls(0).set_flag(.variadic)
|
||||
}
|
||||
for i, arg_name in arg_names {
|
||||
alanguage := p.table.sym(typ).language
|
||||
|
@ -97,3 +97,20 @@ fn test_fn_variadic_method_no_args() {
|
||||
a := VaTestStruct{}
|
||||
a.variadic_method_no_args('marko')
|
||||
}
|
||||
|
||||
// test vargs with pointer type
|
||||
fn take_variadic_string_ptr(strings ...&string) {
|
||||
take_array_string_ptr(strings)
|
||||
}
|
||||
|
||||
fn take_array_string_ptr(strings []&string) {
|
||||
assert strings.len == 2
|
||||
assert *strings[0] == 'a'
|
||||
assert *strings[1] == 'b'
|
||||
}
|
||||
|
||||
fn test_varg_pointer() {
|
||||
a := 'a'
|
||||
b := 'b'
|
||||
take_variadic_string_ptr(&a, &b)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user