diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 7e6921bbb1..bcc5546259 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -310,6 +310,17 @@ pub fn (t Type) is_ptr() bool { return (int(t) >> 16) & 0xff > 0 } +[inline] +pub fn (typ Type) is_pointer() bool { + // builtin pointer types (voidptr, byteptr, charptr) + return typ.idx() in ast.pointer_type_idxs +} + +[inline] +pub fn (typ Type) is_voidptr() bool { + return typ.idx() == ast.voidptr_type_idx +} + [inline] pub fn (t Type) is_any_kind_of_pointer() bool { return (int(t) >> 16) & 0xff > 0 || (u16(t) & 0xffff) in ast.pointer_type_idxs @@ -471,22 +482,6 @@ pub fn new_type_ptr(idx int, nr_muls int) Type { return (u32(nr_muls) << 16) | u16(idx) } -[inline] -pub fn (typ Type) is_pointer() bool { - // builtin pointer types (voidptr, byteptr, charptr) - return typ.idx() in ast.pointer_type_idxs -} - -[inline] -pub fn (typ Type) is_voidptr() bool { - return typ.idx() == ast.voidptr_type_idx -} - -[inline] -pub fn (typ Type) is_real_pointer() bool { - return typ.is_ptr() || typ.is_pointer() -} - [inline] pub fn (typ Type) is_float() bool { return !typ.is_ptr() && typ.idx() in ast.float_type_idxs diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index fab84b0fb9..4933cb02be 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -271,13 +271,13 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { } } // Do not allow `a := 0; b := 0; a = &b` - if !is_decl && left is ast.Ident && !is_blank_ident && !left_type.is_real_pointer() - && right_type.is_real_pointer() && !right_type.has_flag(.shared_f) { + if !is_decl && left is ast.Ident && !is_blank_ident && !left_type.is_any_kind_of_pointer() + && right_type.is_any_kind_of_pointer() && !right_type.has_flag(.shared_f) { left_sym := c.table.sym(left_type) if left_sym.kind !in [.function, .array] { c.warn( 'cannot assign a reference to a value (this will be an error soon) left=${c.table.type_str(left_type)} ${left_type.is_ptr()} ' + - 'right=${c.table.type_str(right_type)} ${right_type.is_real_pointer()} ptr=${right_type.is_ptr()}', + 'right=${c.table.type_str(right_type)} ${right_type.is_any_kind_of_pointer()} ptr=${right_type.is_ptr()}', node.pos) } } diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index a5bc629621..7f19caaeaa 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -132,7 +132,7 @@ fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool { } // allow direct int-literal assignment for pointers for now // maybe in the future options should be used for that - if expected.is_real_pointer() { + if expected.is_any_kind_of_pointer() { if got == ast.int_literal_type { return true } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b601c161fa..50dafb4f67 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3016,7 +3016,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { ft := c.table.type_to_str(from_type) c.error('cannot cast type `${ft}` to string, use `${snexpr}.str()` instead.', node.pos) - } else if from_type.is_real_pointer() { + } else if from_type.is_any_kind_of_pointer() { snexpr := node.expr.str() ft := c.table.type_to_str(from_type) c.error('cannot cast pointer type `${ft}` to string, use `&u8(${snexpr}).vstring()` or `cstring_to_vstring(${snexpr})` instead.', @@ -4092,7 +4092,7 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { if !c.inside_unsafe && !c.is_builtin_mod && !c.inside_if_guard && !c.is_index_assign && typ_sym.kind == .map && node.or_expr.stmts.len == 0 { elem_type := c.table.value_type(typ) - if elem_type.is_real_pointer() { + if elem_type.is_any_kind_of_pointer() { c.note('accessing a pointer map value requires an `or {}` block outside `unsafe`', node.pos) } diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index f91a0bd523..63f40e1b03 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -199,7 +199,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { c.expected_type = elem_type continue } else { - if !typ.is_real_pointer() && !typ.is_int() && is_first_elem_ptr { + if !typ.is_any_kind_of_pointer() && !typ.is_int() && is_first_elem_ptr { c.error('cannot have non-pointer of type `${c.table.type_to_str(typ)}` in a pointer array of type `${c.table.type_to_str(elem_type)}`', expr.pos()) } diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index b2ecd817c8..b13eeccc38 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1167,7 +1167,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. } continue } - if param.typ.is_ptr() && !param.is_mut && !call_arg.typ.is_real_pointer() + if param.typ.is_ptr() && !param.is_mut && !call_arg.typ.is_any_kind_of_pointer() && call_arg.expr.is_literal() && func.language == .v && !c.pref.translated { c.error('literal argument cannot be passed as reference parameter `${c.table.type_to_str(param.typ)}`', call_arg.pos) @@ -2049,7 +2049,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { if final_arg_sym.kind == .none_ && param.typ.has_flag(.generic) { c.error('cannot use `none` as generic argument', arg.pos) } - if param.typ.is_ptr() && !arg.typ.is_real_pointer() && arg.expr.is_literal() + if param.typ.is_ptr() && !arg.typ.is_any_kind_of_pointer() && arg.expr.is_literal() && !c.pref.translated { c.error('literal argument cannot be passed as reference parameter `${c.table.type_to_str(param.typ)}`', arg.pos) diff --git a/vlib/v/checker/return.v b/vlib/v/checker/return.v index 58014b2494..a46030fc3d 100644 --- a/vlib/v/checker/return.v +++ b/vlib/v/checker/return.v @@ -229,8 +229,8 @@ fn (mut c Checker) return_stmt(mut node ast.Return) { pos) } } - if got_type.is_real_pointer() && !exp_type.is_real_pointer() - && !c.table.unaliased_type(exp_type).is_real_pointer() { + if got_type.is_any_kind_of_pointer() && !exp_type.is_any_kind_of_pointer() + && !c.table.unaliased_type(exp_type).is_any_kind_of_pointer() { pos := node.exprs[expr_idxs[i]].pos() if node.exprs[expr_idxs[i]].is_auto_deref_var() { continue @@ -239,8 +239,8 @@ fn (mut c Checker) return_stmt(mut node ast.Return) { c.error('fn `${c.table.cur_fn.name}` expects you to return a non reference type `${c.table.type_to_str(exp_type)}`, but you are returning `${c.table.type_to_str(got_type)}` instead', pos) } - if exp_type.is_real_pointer() && !got_type.is_real_pointer() - && !c.table.unaliased_type(got_type).is_real_pointer() + if exp_type.is_any_kind_of_pointer() && !got_type.is_any_kind_of_pointer() + && !c.table.unaliased_type(got_type).is_any_kind_of_pointer() && got_type != ast.int_literal_type && !c.pref.translated && !c.file.is_translated { pos := node.exprs[expr_idxs[i]].pos() if node.exprs[expr_idxs[i]].is_auto_deref_var() { diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 86341c9f2a..b4ef2f26da 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -139,7 +139,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { && c.type_implements(field.default_expr_typ, field.typ, field.pos) c.check_expected(field.default_expr_typ, field.typ) or { if sym.kind == .interface_ && interface_implemented { - if !c.inside_unsafe && !field.default_expr_typ.is_real_pointer() { + if !c.inside_unsafe && !field.default_expr_typ.is_any_kind_of_pointer() { if c.table.sym(field.default_expr_typ).kind != .interface_ { c.mark_as_referenced(mut &node.fields[i].default_expr, true) @@ -151,7 +151,8 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { } } if field.default_expr.is_nil() { - if !field.typ.is_real_pointer() && c.table.sym(field.typ).kind != .function { + if !field.typ.is_any_kind_of_pointer() + && c.table.sym(field.typ).kind != .function { c.error('cannot assign `nil` to a non-pointer field', field.type_pos) } } @@ -522,7 +523,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini if exp_type_sym.kind == .interface_ { if c.type_implements(got_type, exp_type, field.pos) { if !c.inside_unsafe && got_type_sym.kind != .interface_ - && !got_type.is_real_pointer() { + && !got_type.is_any_kind_of_pointer() { c.mark_as_referenced(mut &field.expr, true) } } @@ -539,8 +540,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini field.pos) } } else { - if exp_type.is_ptr() && !got_type.is_real_pointer() && field.expr.str() != '0' - && !exp_type.has_flag(.option) { + if exp_type.is_ptr() && !got_type.is_any_kind_of_pointer() + && field.expr.str() != '0' && !exp_type.has_flag(.option) { c.error('reference field must be initialized with reference', field.pos) } @@ -623,7 +624,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini info.fields[i].default_expr_typ = ast.new_type(idx) } } else if field.default_expr.is_nil() { - if field.typ.is_real_pointer() { + if field.typ.is_any_kind_of_pointer() { info.fields[i].default_expr_typ = field.typ } } else { diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 3617b32014..894b1477e3 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -2142,8 +2142,8 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) { 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_sym := g.table.sym(arg_typ) - exp_is_ptr := expected_type.is_real_pointer() - arg_is_ptr := arg_typ.is_real_pointer() + exp_is_ptr := expected_type.is_any_kind_of_pointer() + arg_is_ptr := arg_typ.is_any_kind_of_pointer() if expected_type == 0 { g.checker_bug('ref_or_deref_arg expected_type is 0', arg.pos) } diff --git a/vlib/v/gen/c/json.v b/vlib/v/gen/c/json.v index 9072cd23f5..5fdea3012b 100644 --- a/vlib/v/gen/c/json.v +++ b/vlib/v/gen/c/json.v @@ -805,7 +805,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st // it has to be encoded as a unix timestamp number enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}._v_unix));') } else { - if !field.typ.is_real_pointer() { + if !field.typ.is_any_kind_of_pointer() { enc.writeln('${indent}\tcJSON_AddItemToObject(o, "${name}", ${enc_name}(${prefix_enc}${op}${c_name(field.name)})); /*A*/') } else { arg_prefix := if field.typ.is_ptr() { '' } else { '*' } diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v index b909091425..b18b1df6a1 100644 --- a/vlib/v/gen/native/amd64.v +++ b/vlib/v/gen/native/amd64.v @@ -537,7 +537,7 @@ fn (mut c Amd64) mov_deref(reg Amd64Register, regptr Amd64Register, typ ast.Type if size !in [1, 2, 4, 8] { c.g.n_error('Invalid size on dereferencing') } - is_signed := !typ.is_real_pointer() && typ.is_signed() + is_signed := !typ.is_any_kind_of_pointer() && typ.is_signed() rex := int(reg) / 8 * 4 + int(regptr) / 8 if size == 4 && !is_signed { if rex > 0 { @@ -628,7 +628,7 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) { size_str = 'BYTE' } else { - if typ.is_real_pointer() { + if typ.is_any_kind_of_pointer() { c.g.write16(0x8948 + if is_extended_register { 4 } else { 0 }) size_str = 'QWORD' } else { @@ -796,7 +796,7 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) { is_far_var := offset > 0x80 || offset < -0x7f typ := if config.typ == 0 { var.typ } else { config.typ } size := c.g.get_type_size(typ) - is_signed := !typ.is_real_pointer() && typ.is_signed() + is_signed := !typ.is_any_kind_of_pointer() && typ.is_signed() instruction, size_str := match true { size == 4 && is_signed { @@ -860,7 +860,7 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) { fn (mut c Amd64) mov_extend_reg(a Amd64Register, b Amd64Register, typ ast.Type) { size := c.g.get_type_size(typ) - is_signed := !typ.is_real_pointer() && typ.is_signed() + is_signed := !typ.is_any_kind_of_pointer() && typ.is_signed() if size in [1, 2, 4] { if size == 4 && !is_signed { @@ -2021,7 +2021,7 @@ fn (mut c Amd64) assign_right_expr(node ast.AssignStmt, i int, right ast.Expr, n } .decl_assign { typ := node.left_types[i] - if typ.is_number() || typ.is_real_pointer() || typ.is_bool() { + if typ.is_number() || typ.is_any_kind_of_pointer() || typ.is_bool() { c.allocate_var(name, c.g.get_type_size(typ), 0) } else { ts := c.g.table.sym(typ) @@ -2038,7 +2038,8 @@ fn (mut c Amd64) assign_right_expr(node ast.AssignStmt, i int, right ast.Expr, n match var_ { LocalVar { var := var_ as LocalVar - if var.typ.is_number() || var.typ.is_real_pointer() || var.typ.is_bool() { + if var.typ.is_number() || var.typ.is_any_kind_of_pointer() + || var.typ.is_bool() { c.mov_var_to_reg(Amd64Register.rax, right as ast.Ident) c.mov_reg_to_var(ident, Amd64Register.rax) } else { @@ -2120,7 +2121,8 @@ fn (mut c Amd64) assign_right_expr(node ast.AssignStmt, i int, right ast.Expr, n match var_ { LocalVar { var := var_ as LocalVar - if var.typ.is_number() || var.typ.is_real_pointer() || var.typ.is_bool() { + if var.typ.is_number() || var.typ.is_any_kind_of_pointer() + || var.typ.is_bool() { c.mov_var_to_reg(Amd64Register.rax, right as ast.Ident) c.mov_reg_to_var(ident, Amd64Register.rax) } else { diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index f15f96b570..ed6ef87836 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -618,7 +618,7 @@ fn (mut g Gen) get_field_offset(typ ast.Type, name string) int { // get type size, and calculate size and align and store them to the cache when the type is struct fn (mut g Gen) get_type_size(typ ast.Type) int { // TODO type flags - if typ.is_real_pointer() { + if typ.is_any_kind_of_pointer() { return 8 } if typ in ast.number_type_idxs { @@ -729,7 +729,8 @@ fn (mut g Gen) get_multi_return(types []ast.Type) MultiReturn { } fn (g Gen) is_register_type(typ ast.Type) bool { - return typ.is_pure_int() || typ == ast.char_type_idx || typ.is_real_pointer() || typ.is_bool() + return typ.is_pure_int() || typ == ast.char_type_idx || typ.is_any_kind_of_pointer() + || typ.is_bool() } fn (mut g Gen) get_sizeof_ident(ident ast.Ident) int { diff --git a/vlib/v/gen/wasm/gen.v b/vlib/v/gen/wasm/gen.v index d1ce9ad08e..f272768f41 100644 --- a/vlib/v/gen/wasm/gen.v +++ b/vlib/v/gen/wasm/gen.v @@ -159,7 +159,8 @@ fn (mut g Gen) function_return_wasm_type(typ ast.Type) binaryen.Type { if typ == ast.void_type { return type_none } - types := g.unpack_type(typ).filter(it.is_real_pointer() || g.table.sym(it).info !is ast.Struct).map(g.get_wasm_type(it)) + types := g.unpack_type(typ).filter(it.is_any_kind_of_pointer() + || g.table.sym(it).info !is ast.Struct).map(g.get_wasm_type(it)) if types.len == 0 { return type_none } @@ -274,7 +275,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) { for idx, typ in g.curr_ret { sym := g.table.sym(typ) - if sym.info is ast.Struct && !typ.is_real_pointer() { + if sym.info is ast.Struct && !typ.is_any_kind_of_pointer() { g.local_temporaries << Temporary{ name: '__return${idx}' typ: type_i32 // pointer @@ -785,7 +786,8 @@ fn (mut g Gen) expr_impl(node ast.Expr, expected ast.Type) binaryen.Expression { } ret_types := g.unpack_type(node.return_type) - structs := ret_types.filter(g.table.sym(it).info is ast.Struct && !it.is_real_pointer()) + structs := ret_types.filter(g.table.sym(it).info is ast.Struct + && !it.is_any_kind_of_pointer()) mut structs_addrs := []int{cap: structs.len} // ABI: {return structs} {method `self`}, then {arguments} @@ -957,7 +959,7 @@ fn (mut g Gen) expr_stmt(node ast.Stmt, expected ast.Type) binaryen.Expression { mut exprs := []binaryen.Expression{cap: node.exprs.len} for idx, expr in node.exprs { typ := g.curr_ret[idx] - if g.table.sym(typ).info is ast.Struct && !typ.is_real_pointer() { + if g.table.sym(typ).info is ast.Struct && !typ.is_any_kind_of_pointer() { // Could be adapted to use random pointers? /* if expr is ast.StructInit { diff --git a/vlib/v/gen/wasm/mem.v b/vlib/v/gen/wasm/mem.v index fdff8fbac9..997b3db62e 100644 --- a/vlib/v/gen/wasm/mem.v +++ b/vlib/v/gen/wasm/mem.v @@ -46,8 +46,8 @@ struct Global { } fn (g Gen) is_pure_type(typ ast.Type) bool { - if typ.is_pure_int() || typ.is_pure_float() || typ == ast.char_type_idx || typ.is_real_pointer() - || typ.is_bool() { + if typ.is_pure_int() || typ.is_pure_float() || typ == ast.char_type_idx + || typ.is_any_kind_of_pointer() || typ.is_bool() { return true } ts := g.table.sym(typ) diff --git a/vlib/v/gen/wasm/ops.v b/vlib/v/gen/wasm/ops.v index 9fab29ad59..c602effd32 100644 --- a/vlib/v/gen/wasm/ops.v +++ b/vlib/v/gen/wasm/ops.v @@ -20,7 +20,7 @@ fn (mut g Gen) get_wasm_type(typ_ ast.Type) binaryen.Type { if typ == ast.void_type_idx { return wasm.type_none } - if typ.is_real_pointer() { + if typ.is_any_kind_of_pointer() { g.needs_stack = true return wasm.type_i32 }