Skip to content

Commit

Permalink
cgen: fix anon struct auto string method generation
Browse files Browse the repository at this point in the history
  • Loading branch information
spytheman committed Jul 10, 2022
1 parent 64eab72 commit 69aaf68
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 1 deletion.
6 changes: 6 additions & 0 deletions vlib/v/ast/table.v
Expand Up @@ -46,6 +46,7 @@ pub mut:
pointer_size int
// cache for type_to_str_using_aliases
cached_type_to_str map[u64]string
anon_struct_names map[string]int // anon struct name -> struct sym idx
}

// used by vls to avoid leaks
Expand Down Expand Up @@ -834,6 +835,11 @@ pub fn (mut t Table) register_enum_decl(enum_decl EnumDecl) {
t.enum_decls[enum_decl.name] = enum_decl
}

[inline]
pub fn (mut t Table) register_anon_struct(name string, sym_idx int) {
t.anon_struct_names[name] = sym_idx
}

pub fn (t &Table) known_type(name string) bool {
return t.find_type_idx(name) != 0 || t.parsing_type == name
}
Expand Down
5 changes: 5 additions & 0 deletions vlib/v/gen/c/cgen.v
Expand Up @@ -1037,8 +1037,13 @@ fn (mut g Gen) write_results() {
}
done << base
g.typedefs.writeln('typedef struct $styp $styp;')
dump(g.result_type_text(styp, base))
g.out_results.write_string(g.result_type_text(styp, base) + ';\n\n')
}
for k, _ in g.table.anon_struct_names {
ck := c_name(k)
g.typedefs.writeln('typedef struct $ck $ck;')
}
}

fn (mut g Gen) find_or_register_shared(t ast.Type, base string) string {
Expand Down
3 changes: 2 additions & 1 deletion vlib/v/gen/c/struct.v
Expand Up @@ -350,7 +350,8 @@ fn (mut g Gen) struct_decl(s ast.Struct, name string, is_anon bool) {
g.type_definitions.writeln(pre_pragma)

if is_anon {
g.type_definitions.writeln('struct {')
g.type_definitions.write_string('\t$name ')
return
} else if s.is_union {
g.type_definitions.writeln('union $name {')
} else {
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/parser/struct.v
Expand Up @@ -350,6 +350,9 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
return ast.StructDecl{}
}
mut ret := p.table.register_sym(sym)
if is_anon {
p.table.register_anon_struct(name, ret)
}
// allow duplicate c struct declarations
if ret == -1 && language != .c {
if _ := p.table.find_fn('main.main') {
Expand Down
8 changes: 8 additions & 0 deletions vlib/v/tests/struct_test.v
Expand Up @@ -447,3 +447,11 @@ fn test_anon() {
assert book2.author.age == 24
println(book2.author.name)
}

fn test_anon_auto_stringify() {
b := Book{}
s := b.str()
assert s.contains('author: ')
assert s.contains('name: ')
assert s.contains('age: 0')
}

0 comments on commit 69aaf68

Please sign in to comment.