Skip to content

Commit

Permalink
cgen: fix struct init for anon struct field on C structs (fix vlang#2…
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Jan 10, 2025
1 parent 3b31699 commit 36154b8
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 15 deletions.
26 changes: 13 additions & 13 deletions vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -424,22 +424,21 @@ pub:
generic_types []Type
is_pub bool
// _pos fields for vfmt
mut_pos int = -1 // mut:
pub_pos int = -1 // pub:
pub_mut_pos int = -1 // pub mut:
global_pos int = -1 // __global:
module_pos int = -1 // module:
language Language
is_union bool
attrs []Attr
pre_comments []Comment
end_comments []Comment
embeds []Embed

mut_pos int = -1 // mut:
pub_pos int = -1 // pub:
pub_mut_pos int = -1 // pub mut:
global_pos int = -1 // __global:
module_pos int = -1 // module:
is_union bool
attrs []Attr
pre_comments []Comment
end_comments []Comment
embeds []Embed
is_implements bool
implements_types []TypeNode
pub mut:
fields []StructField
language Language
fields []StructField
}

pub struct Embed {
Expand Down Expand Up @@ -522,6 +521,7 @@ pub mut:
has_update_expr bool // has `...a`
init_fields []StructInitField
generic_types []Type
language Language
}

pub enum StructInitKind {
Expand Down
8 changes: 6 additions & 2 deletions vlib/v/gen/c/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
}
}
if is_anon {
g.writeln('(${styp}){')
if node.language == .v {
g.write('(${styp})')
}
g.writeln('{')
} else if g.is_shared && !g.inside_opt_data && !g.is_arraymap_set {
mut shared_typ := node.typ.set_flag(.shared_f)
shared_styp = g.styp(shared_typ)
Expand Down Expand Up @@ -433,7 +436,8 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool {
}
if has_option_field || field.anon_struct_decl.fields.len > 0 {
default_init := ast.StructInit{
typ: field.typ
typ: field.typ
language: field.anon_struct_decl.language
}
g.write('.${field_name} = ')
if field.typ.has_flag(.option) {
Expand Down
1 change: 1 addition & 0 deletions vlib/v/parser/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
if p.tok.kind == .key_struct {
// Anon structs
p.anon_struct_decl = p.struct_decl(true)
p.anon_struct_decl.language = language
// Find the registered anon struct type, it was registered above in `p.struct_decl()`
typ = p.table.find_type_idx(p.anon_struct_decl.name)
} else {
Expand Down
11 changes: 11 additions & 0 deletions vlib/v/tests/c_structs/anon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// anon.h
#ifndef TEST_H
#define TEST_H

typedef struct {
struct {
int x;
} inner;
} outer;

#endif
19 changes: 19 additions & 0 deletions vlib/v/tests/c_structs/cstruct_anon_test.c.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#insert "@VMODROOT/anon.h"

@[typedef]
struct C.outer {
inner struct {
x int
}
}

struct Outer {
inner struct {
val int
}
}

fn test_main() {
_ = Outer{}
_ = C.outer{}
}

0 comments on commit 36154b8

Please sign in to comment.