mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
ast,cgen: support a := Abc{unsafe{nil}}
, for struct Abc { next &Abc }
This commit is contained in:
@ -471,7 +471,7 @@ pub const (
|
|||||||
number_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i64_type_idx, u8_type_idx,
|
number_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i64_type_idx, u8_type_idx,
|
||||||
char_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, isize_type_idx, usize_type_idx,
|
char_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, isize_type_idx, usize_type_idx,
|
||||||
f32_type_idx, f64_type_idx, int_literal_type_idx, float_literal_type_idx, rune_type_idx]
|
f32_type_idx, f64_type_idx, int_literal_type_idx, float_literal_type_idx, rune_type_idx]
|
||||||
pointer_type_idxs = [voidptr_type_idx, byteptr_type_idx, charptr_type_idx]
|
pointer_type_idxs = [voidptr_type_idx, byteptr_type_idx, charptr_type_idx, nil_type_idx]
|
||||||
string_type_idxs = [string_type_idx]
|
string_type_idxs = [string_type_idx]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -70,26 +70,10 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
|
|||||||
}
|
}
|
||||||
inited_fields[field.name] = i
|
inited_fields[field.name] = i
|
||||||
if sym.kind != .struct_ {
|
if sym.kind != .struct_ {
|
||||||
field_name := if sym.language == .v { c_name(field.name) } else { field.name }
|
|
||||||
g.write('.$field_name = ')
|
|
||||||
if field.typ == 0 {
|
if field.typ == 0 {
|
||||||
g.checker_bug('struct init, field.typ is 0', field.pos)
|
g.checker_bug('struct init, field.typ is 0', field.pos)
|
||||||
}
|
}
|
||||||
field_type_sym := g.table.sym(field.typ)
|
g.struct_init_field(field, sym.language)
|
||||||
mut cloned := false
|
|
||||||
if g.is_autofree && !field.typ.is_ptr() && field_type_sym.kind in [.array, .string] {
|
|
||||||
g.write('/*clone1*/')
|
|
||||||
if g.gen_clone_assignment(field.expr, field.typ, false) {
|
|
||||||
cloned = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !cloned {
|
|
||||||
if (field.expected_type.is_ptr() && !field.expected_type.has_flag(.shared_f))
|
|
||||||
&& !(field.typ.is_ptr() || field.typ.is_pointer()) && !field.typ.is_number() {
|
|
||||||
g.write('/* autoref */&')
|
|
||||||
}
|
|
||||||
g.expr_with_cast(field.expr, field.typ, field.expected_type)
|
|
||||||
}
|
|
||||||
if i != node.fields.len - 1 {
|
if i != node.fields.len - 1 {
|
||||||
if is_multiline {
|
if is_multiline {
|
||||||
g.writeln(',')
|
g.writeln(',')
|
||||||
@ -167,44 +151,10 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
|
|||||||
}
|
}
|
||||||
if field.name in inited_fields {
|
if field.name in inited_fields {
|
||||||
sfield := node.fields[inited_fields[field.name]]
|
sfield := node.fields[inited_fields[field.name]]
|
||||||
field_name := if sym.language == .v { c_name(field.name) } else { field.name }
|
|
||||||
if sfield.typ == 0 {
|
if sfield.typ == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
g.write('.$field_name = ')
|
g.struct_init_field(sfield, sym.language)
|
||||||
field_type_sym := g.table.sym(sfield.typ)
|
|
||||||
mut cloned := false
|
|
||||||
if g.is_autofree && !sfield.typ.is_ptr() && field_type_sym.kind in [.array, .string] {
|
|
||||||
g.write('/*clone1*/')
|
|
||||||
if g.gen_clone_assignment(sfield.expr, sfield.typ, false) {
|
|
||||||
cloned = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !cloned {
|
|
||||||
inside_cast_in_heap := g.inside_cast_in_heap
|
|
||||||
g.inside_cast_in_heap = 0 // prevent use of pointers in child structs
|
|
||||||
|
|
||||||
if field_type_sym.kind == .array_fixed && sfield.expr is ast.Ident {
|
|
||||||
fixed_array_info := field_type_sym.info as ast.ArrayFixed
|
|
||||||
g.write('{')
|
|
||||||
for i in 0 .. fixed_array_info.size {
|
|
||||||
g.expr(sfield.expr)
|
|
||||||
g.write('[$i]')
|
|
||||||
if i != fixed_array_info.size - 1 {
|
|
||||||
g.write(', ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.write('}')
|
|
||||||
} else {
|
|
||||||
if (sfield.expected_type.is_ptr()
|
|
||||||
&& !sfield.expected_type.has_flag(.shared_f)) && !(sfield.typ.is_ptr()
|
|
||||||
|| sfield.typ.is_pointer()) && !sfield.typ.is_number() {
|
|
||||||
g.write('/* autoref */&')
|
|
||||||
}
|
|
||||||
g.expr_with_cast(sfield.expr, sfield.typ, sfield.expected_type)
|
|
||||||
}
|
|
||||||
g.inside_cast_in_heap = inside_cast_in_heap // restore value for further struct inits
|
|
||||||
}
|
|
||||||
if is_multiline {
|
if is_multiline {
|
||||||
g.writeln(',')
|
g.writeln(',')
|
||||||
} else {
|
} else {
|
||||||
@ -434,3 +384,41 @@ fn (mut g Gen) struct_decl(s ast.Struct, name string, is_anon bool) {
|
|||||||
g.type_definitions.writeln('\n')
|
g.type_definitions.writeln('\n')
|
||||||
g.type_definitions.writeln(post_pragma)
|
g.type_definitions.writeln(post_pragma)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Language) {
|
||||||
|
field_name := if language == .v { c_name(sfield.name) } else { sfield.name }
|
||||||
|
g.write('.$field_name = ')
|
||||||
|
field_type_sym := g.table.sym(sfield.typ)
|
||||||
|
mut cloned := false
|
||||||
|
if g.is_autofree && !sfield.typ.is_ptr() && field_type_sym.kind in [.array, .string] {
|
||||||
|
g.write('/*clone1*/')
|
||||||
|
if g.gen_clone_assignment(sfield.expr, sfield.typ, false) {
|
||||||
|
cloned = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !cloned {
|
||||||
|
inside_cast_in_heap := g.inside_cast_in_heap
|
||||||
|
g.inside_cast_in_heap = 0 // prevent use of pointers in child structs
|
||||||
|
|
||||||
|
if field_type_sym.kind == .array_fixed && sfield.expr is ast.Ident {
|
||||||
|
fixed_array_info := field_type_sym.info as ast.ArrayFixed
|
||||||
|
g.write('{')
|
||||||
|
for i in 0 .. fixed_array_info.size {
|
||||||
|
g.expr(sfield.expr)
|
||||||
|
g.write('[$i]')
|
||||||
|
if i != fixed_array_info.size - 1 {
|
||||||
|
g.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.write('}')
|
||||||
|
} else {
|
||||||
|
if sfield.typ != ast.nil_type
|
||||||
|
&& (sfield.expected_type.is_ptr() && !sfield.expected_type.has_flag(.shared_f))
|
||||||
|
&& !(sfield.typ.is_ptr() || sfield.typ.is_pointer()) && !sfield.typ.is_number() {
|
||||||
|
g.write('/* autoref */&')
|
||||||
|
}
|
||||||
|
g.expr_with_cast(sfield.expr, sfield.typ, sfield.expected_type)
|
||||||
|
}
|
||||||
|
g.inside_cast_in_heap = inside_cast_in_heap // restore value for further struct inits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user