diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 75425ff731..d6a28aa994 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -993,6 +993,9 @@ pub fn (mut g Gen) init() { g.cheaders.writeln('#define VNOFLOAT 1') } g.cheaders.writeln(c_builtin_types) + if !g.pref.skip_unused || g.table.used_features.used_maps > 0 { + g.cheaders.writeln(c_mapfn_callback_types) + } if g.pref.is_bare { g.cheaders.writeln(c_bare_headers) } else { @@ -1752,6 +1755,9 @@ static inline void __${sym.cname}_pushval(${sym.cname} ch, ${push_arg} val) { } } .map { + if g.pref.skip_unused && g.table.used_features.used_maps == 0 { + continue + } g.type_definitions.writeln('typedef map ${sym.cname};') } else { @@ -1885,7 +1891,6 @@ pub fn (mut g Gen) write_fn_typesymbol_declaration(sym ast.TypeSymbol) { if !info.has_decl && (not_anon || is_fn_sig) && !func.return_type.has_flag(.generic) && !has_generic_arg { fn_name := sym.cname - mut call_conv := '' mut msvc_call_conv := '' for attr in func.attrs { @@ -6642,6 +6647,11 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) { g.typedefs.writeln('typedef struct none none;') } mut name := sym.scoped_cname() + if g.pref.skip_unused && g.table.used_features.used_maps == 0 { + if name in ['map', 'mapnode', 'SortedMap', 'MapMode', 'DenseArray'] { + continue + } + } match sym.info { ast.Struct { if !struct_names[name] { diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index 63a06059e2..5d286d6ad8 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -780,7 +780,9 @@ typedef struct sync__Channel* chan; #endif #endif #endif +' +const c_mapfn_callback_types = ' typedef u64 (*MapHashFn)(voidptr); typedef bool (*MapEqFn)(voidptr, voidptr); typedef void (*MapCloneFn)(voidptr, voidptr); diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index e9067f109a..2569e75b6c 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -505,7 +505,8 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a } } } else { - for map_fn_name in ['new_map', 'new_map_init', 'map_hash_string', 'new_dense_array'] { + for map_fn_name in ['new_map', 'new_map_init', 'map_hash_string', 'new_dense_array', + 'new_dense_array_noscan'] { walker.used_fns.delete(map_fn_name) } for k, mut mfn in all_fns { diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index 4e0bbc88a3..5c3bd5604b 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -16,6 +16,7 @@ pub mut: used_globals map[string]bool used_structs map[string]bool used_fields map[string]bool + used_ifaces map[string]bool used_none int n_asserts int pref &pref.Preferences = unsafe { nil } @@ -358,6 +359,9 @@ fn (mut w Walker) expr(node_ ast.Expr) { if node.is_vweb { w.stmts(node.veb_tmpl.stmts) } + if node.is_embed { + w.features.used_maps++ + } } ast.DumpExpr { w.expr(node.expr) @@ -515,6 +519,10 @@ fn (mut w Walker) expr(node_ ast.Expr) { ast.SelectorExpr { w.expr(node.expr) if node.expr_type != 0 { + esym := w.table.sym(node.expr_type) + if esym.kind == .interface { + w.mark_interface_by_symbol(esym) + } if method := w.table.find_method(w.table.sym(node.expr_type), node.field_name) { w.fn_by_name(method.fkey()) } @@ -683,6 +691,7 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { } } } else if left_sym.info is ast.Interface { + w.mark_interface_by_symbol(left_sym) for typ in left_sym.info.types { sym := w.table.sym(typ) _, embed_types := w.table.find_method_from_embeds(sym, node.name) or { @@ -777,3 +786,18 @@ pub fn (mut w Walker) or_block(node ast.OrExpr) { w.stmts(node.stmts) } } + +pub fn (mut w Walker) mark_interface_by_symbol(isym ast.TypeSymbol) { + if isym.name in w.used_ifaces { + return + } + w.used_ifaces[isym.name] = true + if isym.info is ast.Interface { + for typ in isym.info.types { + if typ == ast.map_type { + w.features.used_maps++ + } + // sym := w.table.sym(typ); eprintln('>>>>>>>>> typ: ${typ.str():-30} | sym.name: ${sym.name}') + } + } +}