v.gen.c: fix codegen ordering problem with interfaces with interface fields (#10862)
parent
677ef7bb08
commit
1db354c360
|
@ -864,6 +864,11 @@ static inline void __${typ.cname}_pushval($typ.cname ch, $el_stype val) {
|
||||||
}
|
}
|
||||||
// Generating interfaces after all the common types have been defined
|
// Generating interfaces after all the common types have been defined
|
||||||
// to prevent generating interface struct before definition of field types
|
// to prevent generating interface struct before definition of field types
|
||||||
|
for typ in g.table.type_symbols {
|
||||||
|
if typ.kind == .interface_ && typ.name !in c.builtins {
|
||||||
|
g.write_interface_typedef(typ)
|
||||||
|
}
|
||||||
|
}
|
||||||
for typ in g.table.type_symbols {
|
for typ in g.table.type_symbols {
|
||||||
if typ.kind == .interface_ && typ.name !in c.builtins {
|
if typ.kind == .interface_ && typ.name !in c.builtins {
|
||||||
g.write_interface_typesymbol_declaration(typ)
|
g.write_interface_typesymbol_declaration(typ)
|
||||||
|
@ -893,13 +898,17 @@ pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) {
|
||||||
g.type_definitions.writeln('typedef $parent_styp $sym.cname;')
|
g.type_definitions.writeln('typedef $parent_styp $sym.cname;')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (mut g Gen) write_interface_typedef(sym ast.TypeSymbol) {
|
||||||
|
struct_name := c_name(sym.cname)
|
||||||
|
g.type_definitions.writeln('typedef struct $struct_name $struct_name;')
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut g Gen) write_interface_typesymbol_declaration(sym ast.TypeSymbol) {
|
pub fn (mut g Gen) write_interface_typesymbol_declaration(sym ast.TypeSymbol) {
|
||||||
info := sym.info as ast.Interface
|
info := sym.info as ast.Interface
|
||||||
if info.is_generic {
|
if info.is_generic {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
struct_name := c_name(sym.cname)
|
struct_name := c_name(sym.cname)
|
||||||
g.type_definitions.writeln('typedef struct $struct_name $struct_name;')
|
|
||||||
g.type_definitions.writeln('struct $struct_name {')
|
g.type_definitions.writeln('struct $struct_name {')
|
||||||
g.type_definitions.writeln('\tunion {')
|
g.type_definitions.writeln('\tunion {')
|
||||||
g.type_definitions.writeln('\t\tvoid* _object;')
|
g.type_definitions.writeln('\t\tvoid* _object;')
|
||||||
|
@ -5386,6 +5395,7 @@ fn (mut g Gen) write_builtin_types() {
|
||||||
for builtin_name in c.builtins {
|
for builtin_name in c.builtins {
|
||||||
sym := g.table.type_symbols[g.table.type_idxs[builtin_name]]
|
sym := g.table.type_symbols[g.table.type_idxs[builtin_name]]
|
||||||
if sym.kind == .interface_ {
|
if sym.kind == .interface_ {
|
||||||
|
g.write_interface_typedef(sym)
|
||||||
g.write_interface_typesymbol_declaration(sym)
|
g.write_interface_typesymbol_declaration(sym)
|
||||||
} else {
|
} else {
|
||||||
builtin_types << sym
|
builtin_types << sym
|
||||||
|
|
|
@ -37,3 +37,29 @@ fn test_interface_nested_field() {
|
||||||
assert ret[0] == 'bar'
|
assert ret[0] == 'bar'
|
||||||
assert ret[1] == 'subbar'
|
assert ret[1] == 'subbar'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Root {
|
||||||
|
v View
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MyRoot {
|
||||||
|
v View
|
||||||
|
}
|
||||||
|
|
||||||
|
interface View {
|
||||||
|
render() int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MyView {}
|
||||||
|
|
||||||
|
fn (m MyView) render() int {
|
||||||
|
return 24
|
||||||
|
}
|
||||||
|
|
||||||
|
fn receive_root(r Root) int {
|
||||||
|
return r.v.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_nested_interface_fields() {
|
||||||
|
assert receive_root(MyRoot{MyView{}}) == 24
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue