From 5b9256ba0b9fe0b879645bf9a8fc8331b1a9a995 Mon Sep 17 00:00:00 2001 From: Lukas Neubert Date: Mon, 31 May 2021 11:26:06 +0200 Subject: [PATCH] cgen: write alias typedefs just before interfaces (#10272) --- vlib/v/gen/c/cgen.v | 49 +++++++++++++---------- vlib/v/tests/alias_custom_type_map_test.v | 8 ++++ vlib/v/tests/modules/geometry/geometry.v | 2 + 3 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 vlib/v/tests/alias_custom_type_map_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 7ab40c2734..19fd5f3c12 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -770,27 +770,6 @@ pub fn (mut g Gen) write_typedef_types() { continue } match typ.kind { - .alias { - parent := unsafe { &g.table.type_symbols[typ.parent_idx] } - is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.` - mut is_typedef := false - if parent.info is ast.Struct { - is_typedef = parent.info.is_typedef - } - mut parent_styp := parent.cname - if is_c_parent { - if !is_typedef { - parent_styp = 'struct ' + parent.cname[3..] - } else { - parent_styp = parent.cname[3..] - } - } else { - if typ.info is ast.Alias { - parent_styp = g.typ(typ.info.parent_type) - } - } - g.type_definitions.writeln('typedef $parent_styp $typ.cname;') - } .array { g.type_definitions.writeln('typedef array $typ.cname;') } @@ -851,7 +830,11 @@ static inline void __${typ.cname}_pushval($typ.cname ch, $el_stype val) { } } } - + for typ in g.table.type_symbols { + if typ.kind == .alias && typ.name !in c.builtins { + g.write_alias_typesymbol_declaration(typ) + } + } // Generating interfaces after all the common types have been defined // to prevent generating interface struct before definition of field types for typ in g.table.type_symbols { @@ -861,6 +844,28 @@ static inline void __${typ.cname}_pushval($typ.cname ch, $el_stype val) { } } +pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) { + parent := unsafe { &g.table.type_symbols[sym.parent_idx] } + is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.` + mut is_typedef := false + if parent.info is ast.Struct { + is_typedef = parent.info.is_typedef + } + mut parent_styp := parent.cname + if is_c_parent { + if !is_typedef { + parent_styp = 'struct ' + parent.cname[3..] + } else { + parent_styp = parent.cname[3..] + } + } else { + if sym.info is ast.Alias { + parent_styp = g.typ(sym.info.parent_type) + } + } + g.type_definitions.writeln('typedef $parent_styp $sym.cname;') +} + pub fn (mut g Gen) write_interface_typesymbol_declaration(sym ast.TypeSymbol) { info := sym.info as ast.Interface g.type_definitions.writeln('typedef struct {') diff --git a/vlib/v/tests/alias_custom_type_map_test.v b/vlib/v/tests/alias_custom_type_map_test.v new file mode 100644 index 0000000000..dd2bcd7492 --- /dev/null +++ b/vlib/v/tests/alias_custom_type_map_test.v @@ -0,0 +1,8 @@ +import geometry + +fn test_aliases_map_init() { + a := geometry.ShapeMap(map{ + geometry.Shape.circle: 'Shape is a circle.' + }) + assert a[geometry.Shape.circle] == 'Shape is a circle.' +} diff --git a/vlib/v/tests/modules/geometry/geometry.v b/vlib/v/tests/modules/geometry/geometry.v index 6535c4851d..4913c21046 100644 --- a/vlib/v/tests/modules/geometry/geometry.v +++ b/vlib/v/tests/modules/geometry/geometry.v @@ -10,6 +10,8 @@ pub enum Shape { triangle } +pub type ShapeMap = map[Shape]string + // used by vlib/v/tests/map_enum_keys_test.v pub enum Form3D { sphere