Skip to content

Commit defdc5e

Browse files
committed
v2: lots of fixes to compile v1
1 parent 0dcbb3a commit defdc5e

25 files changed

Lines changed: 13126 additions & 1400 deletions

vlib/v2/builder/builder.v

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ fn sanitize_staged_c_source(c_source string) string {
109109
// UdpSocket result pointer auto-deref: .sock field is UdpSocket (value), result contains &UdpSocket.
110110
source = source.replace('.sock = (*(net__UdpSocket**)(((u8*)(&_or_t54.err)) + sizeof(IError)))',
111111
'.sock = *(*(net__UdpSocket**)(((u8*)(&_or_t54.err)) + sizeof(IError)))')
112-
// Generic function specialization: convert_voidptr_to_t_T -> convert_voidptr_to_t_f64
113-
source = source.replace('sync__convert_voidptr_to_t_T(', 'sync__convert_voidptr_to_t_f64(')
114112
source = ensure_string_eq_impl(source)
115113
// ObjC .m file references g_vui_webview_cookie_val as a global variable.
116114
// The cleanc backend uses DarwinWebViewState singleton instead.

vlib/v2/gen/cleanc/array.v

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,15 @@ fn (mut g Gen) array_append_elem_type(lhs ast.Expr, rhs ast.Expr) (bool, string)
326326
}
327327
}
328328
}
329+
if is_generic_placeholder_c_type_name(elem_type) {
330+
rhs_value := append_rhs_value_expr(rhs)
331+
if rhs_value is ast.PrefixExpr && rhs_value.op == .mul && rhs_value.expr is ast.CastExpr {
332+
target_type := g.expr_type_to_c(rhs_value.expr.typ)
333+
if target_type.ends_with('*') {
334+
elem_type = target_type.trim_right('*')
335+
}
336+
}
337+
}
329338
// When raw_type gives a module-qualified name (e.g. term__Coord) but the rhs
330339
// is a local struct (e.g. Coord), prefer the rhs type to match the actual typedef.
331340
if elem_type.contains('__') {
@@ -342,14 +351,40 @@ fn (mut g Gen) array_append_elem_type(lhs ast.Expr, rhs ast.Expr) (bool, string)
342351
return true, unmangle_c_ptr_type(elem_type)
343352
}
344353

354+
fn append_rhs_value_expr(expr ast.Expr) ast.Expr {
355+
if expr is ast.UnsafeExpr && expr.stmts.len > 0 {
356+
last := expr.stmts[expr.stmts.len - 1]
357+
if last is ast.ExprStmt {
358+
return last.expr
359+
}
360+
}
361+
return expr
362+
}
363+
345364
fn (mut g Gen) expr_is_array_value(expr ast.Expr) bool {
346365
if expr is ast.ParenExpr {
347366
return g.expr_is_array_value(expr.expr)
348367
}
368+
if expr is ast.UnsafeExpr {
369+
return g.expr_is_array_value(append_rhs_value_expr(expr))
370+
}
349371
if expr is ast.PrefixExpr && expr.op == .mul {
350372
// `*ptr_to_array` is an array value.
351373
return g.expr_is_array_value(expr.expr)
352374
}
375+
if expr is ast.Ident {
376+
if local_type := g.get_local_var_c_type(expr.name) {
377+
if local_type == 'array' || local_type.starts_with('Array_') {
378+
return true
379+
}
380+
}
381+
}
382+
if expr is ast.SelectorExpr {
383+
field_type := g.selector_field_type(expr)
384+
if field_type == 'array' || field_type.starts_with('Array_') {
385+
return true
386+
}
387+
}
353388
expr_type := g.get_expr_type(expr)
354389
if expr_type == 'array' || expr_type.starts_with('Array_') {
355390
return true
@@ -875,27 +910,8 @@ fn (mut g Gen) gen_typed_array_eq(elem_type string, call_args []ast.Expr) {
875910
struct_type := g.lookup_struct_type_by_c_name(elem_type)
876911
if struct_type.fields.len > 0 {
877912
for field in struct_type.fields {
878-
fname := field.name
879-
ftype := field.typ
880-
match ftype {
881-
types.String {
882-
g.sb.writeln(' if (!string__eq(_sa.${fname}, _sb.${fname})) _eq = false;')
883-
}
884-
types.Map {
885-
c_type := g.types_type_to_c(ftype)
886-
if c_type.starts_with('Map_') {
887-
g.sb.writeln(' if (!${c_type}_map_eq(_sa.${fname}, _sb.${fname})) _eq = false;')
888-
} else {
889-
g.sb.writeln(' if (!map_map_eq(_sa.${fname}, _sb.${fname})) _eq = false;')
890-
}
891-
}
892-
types.Array {
893-
g.sb.writeln(' if (!__v2_array_eq(_sa.${fname}, _sb.${fname})) _eq = false;')
894-
}
895-
else {
896-
g.sb.writeln(' if (_sa.${fname} != _sb.${fname}) _eq = false;')
897-
}
898-
}
913+
eq_expr := g.eq_expr_for_type(field.typ, '_sa.${field.name}', '_sb.${field.name}')
914+
g.sb.writeln(' if (!(${eq_expr})) _eq = false;')
899915
}
900916
} else {
901917
// Struct not found, fall back to memcmp

vlib/v2/gen/cleanc/assign.v

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
7373
}
7474
g.write_indent()
7575
g.sb.write_string('${typ} ${name} = ')
76-
g.expr(rhs_expr)
76+
if typ == 'string' && is_none_like_expr(rhs_expr) {
77+
g.sb.write_string('((string){.str = "", .len = 0, .is_lit = 1})')
78+
} else {
79+
g.expr(rhs_expr)
80+
}
7781
g.sb.writeln(';')
7882
g.remember_runtime_local_type(name, typ)
7983
}
@@ -314,6 +318,8 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
314318
// Rename V variables that clash with C type names
315319
if name == 'array' {
316320
name = '_v_array'
321+
} else {
322+
name = escape_c_keyword(name)
317323
}
318324
// Keep fixed-size arrays as C arrays in local declarations.
319325
if rhs is ast.ArrayInitExpr {
@@ -364,6 +370,14 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
364370
}
365371
}
366372
mut typ := g.get_expr_type(rhs)
373+
mut type_from_selector_field := false
374+
if rhs is ast.SelectorExpr {
375+
field_type := g.selector_field_type(rhs)
376+
if field_type != '' {
377+
typ = field_type
378+
type_from_selector_field = true
379+
}
380+
}
367381
// For Ident RHS referencing a struct-typed constant (e.g., `col := no_color`
368382
// where no_color is `#define`d as a Color struct literal), use the const type.
369383
if (typ == 'int' || typ == '') && rhs is ast.Ident {
@@ -383,13 +397,27 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
383397
typ = cast_type
384398
}
385399
}
400+
if rhs is ast.PrefixExpr && rhs.op == .mul && rhs.expr is ast.CastExpr {
401+
cast_type := g.expr_type_to_c(rhs.expr.typ)
402+
if cast_type.ends_with('*') {
403+
typ = cast_type.trim_right('*')
404+
}
405+
}
406+
rhs_is_concrete_literal := rhs is ast.BasicLiteral || rhs is ast.StringLiteral
386407
// For temp variables registered by the transformer with a specific type,
387408
// prefer the scope-registered type over the RHS expression type.
388409
if name.starts_with('_or_t') || name.starts_with('_tmp_') || name.starts_with('_defer_t') {
389410
if raw_type := g.get_raw_type(lhs) {
390411
scope_type := g.types_type_to_c(raw_type)
391412
if scope_type != '' && scope_type != 'int' {
392-
typ = scope_type
413+
generic_container_fallback :=
414+
(typ == 'array' && scope_type.starts_with('Array_'))
415+
|| (typ == 'map' && scope_type.starts_with('Map_'))
416+
if !rhs_is_concrete_literal && !type_from_selector_field && (typ == ''
417+
|| typ == 'int' || typ == 'int_literal' || typ == 'void*'
418+
|| typ == 'voidptr' || generic_container_fallback) {
419+
typ = scope_type
420+
}
393421
// Ensure result/option wrapper types are registered so their
394422
// typedef and struct definitions get emitted in the C output.
395423
if scope_type.starts_with('_result_') || scope_type.starts_with('_option_') {
@@ -456,6 +484,14 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
456484
typ = target_type + '*'
457485
}
458486
}
487+
mut type_from_typed_deref := false
488+
if rhs is ast.PrefixExpr && rhs.op == .mul && rhs.expr is ast.CastExpr {
489+
target_type := g.expr_type_to_c(rhs.expr.typ)
490+
if target_type.ends_with('*') {
491+
typ = target_type[..target_type.len - 1]
492+
type_from_typed_deref = true
493+
}
494+
}
459495
mut elem_type_from_array := false
460496
if rhs is ast.CallExpr {
461497
if rhs.lhs is ast.Ident
@@ -541,7 +577,8 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
541577
type_from_tuple_field = sel_lhs.name.starts_with('_tuple_t')
542578
}
543579
}
544-
if !elem_type_from_array && !type_from_tuple_field && name != ''
580+
if !elem_type_from_array && !type_from_selector_field && !type_from_tuple_field
581+
&& !rhs_is_concrete_literal && !type_from_typed_deref && name != ''
545582
&& g.cur_fn_scope != unsafe { nil } {
546583
if obj := g.cur_fn_scope.lookup_parent(name, 0) {
547584
if obj !is types.Module {
@@ -584,6 +621,12 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
584621
}
585622
}
586623
}
624+
if typ == '' || typ == 'int' || typ == 'int_literal' {
625+
fn_ptr_ret := g.fn_pointer_return_type(rhs.lhs)
626+
if fn_ptr_ret != '' && fn_ptr_ret != 'int' && fn_ptr_ret != 'void' {
627+
typ = fn_ptr_ret
628+
}
629+
}
587630
// For interface vtable method calls (e.g., w->size(w->_object)),
588631
// look up the method's return type from the interface declaration.
589632
if (typ == '' || typ == 'int') && rhs.lhs is ast.SelectorExpr {
@@ -623,7 +666,17 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
623666
is_or_tmp := rhs.lhs is ast.Ident && rhs.lhs.name.starts_with('_or_t')
624667
if container_type.starts_with('_result_') || container_type.starts_with('_option_')
625668
|| is_or_tmp {
626-
cast_type := if typ != '' && typ != 'int_literal' && typ != 'float_literal' {
669+
payload_type := if container_type.starts_with('_result_') {
670+
g.result_value_type(container_type)
671+
} else if container_type.starts_with('_option_') {
672+
option_value_type(container_type)
673+
} else {
674+
''
675+
}
676+
cast_type := if payload_type != '' {
677+
payload_type
678+
} else if typ != '' && typ != 'int_literal' && typ != 'float_literal'
679+
&& !typ.starts_with('_result_') && !typ.starts_with('_option_') {
627680
typ
628681
} else if rhs_type != '' && rhs_type != 'int_literal' && rhs_type != 'float_literal' {
629682
rhs_type
@@ -832,6 +885,11 @@ fn (mut g Gen) gen_assign_stmt(node ast.AssignStmt) {
832885
if typ == '' || typ == 'void' {
833886
typ = 'int'
834887
}
888+
g.register_alias_type(typ)
889+
if typ.starts_with('Array_') && !typ.starts_with('Array_fixed_') && !typ.ends_with('*') {
890+
g.sb.writeln('typedef array ${typ};')
891+
g.write_indent()
892+
}
835893
// Check if declaring an interface pointer initialized with a concrete type
836894
if typ.ends_with('*') && name != '' {
837895
decl_base := typ.trim_right('*')

0 commit comments

Comments
 (0)