cgen,markused: skip struct map { and related type declarations, when no V maps are used (#24826)

This commit is contained in:
Delyan Angelov 2025-07-01 18:40:47 +03:00 committed by GitHub
parent 2c063ea191
commit 46358b011f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 39 additions and 2 deletions

View file

@ -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] {

View file

@ -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);

View file

@ -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 {

View file

@ -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}')
}
}
}