diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index b707f397ee..c856e7a662 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -367,6 +367,7 @@ pub: is_main bool // true for `fn main()` is_test bool // true for `fn test_abcde` is_conditional bool // true for `[if abc] fn abc(){}` + is_exported bool // true for `[export: 'exact_C_name']` is_keep_alive bool // passed memory must not be freed (by GC) before function returns receiver StructField // TODO this is not a struct field receiver_pos token.Position // `(u User)` in `fn (u User) name()` position diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index cbd83b101f..de8baa1164 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -103,6 +103,18 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F 'os.init_os_args', 'os.init_os_args_wide', ] + + if pref.is_bare { + all_fn_root_names << [ + 'strlen', + 'memcmp', + 'memcpy', + 'realloc', + 'vsnprintf', + 'vsprintf', + ] + } + if pref.gc_mode in [.boehm_full_opt, .boehm_incr_opt] { all_fn_root_names << [ '__new_array_noscan', @@ -232,6 +244,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F all_consts: all_consts } // println( all_fns.keys() ) + walker.mark_exported_fns() walker.mark_root_fns(all_fn_root_names) if walker.n_asserts > 0 { diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index 22037ac1e0..a42ca7ba6d 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -46,6 +46,14 @@ pub fn (mut w Walker) mark_root_fns(all_fn_root_names []string) { } } +pub fn (mut w Walker) mark_exported_fns() { + for _, mut func in w.all_fns { + if func.is_exported { + w.fn_decl(mut func) + } + } +} + pub fn (mut w Walker) stmt(node ast.Stmt) { match mut node { ast.EmptyStmt {} diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index e3cf22d809..532628430c 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -180,6 +180,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { conditional_ctdefine := p.attrs.find_comptime_define() or { '' } mut is_unsafe := p.attrs.contains('unsafe') is_keep_alive := p.attrs.contains('keep_args_alive') + is_exported := p.attrs.contains('export') is_pub := p.tok.kind == .key_pub if is_pub { p.next() @@ -423,6 +424,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { params: params is_manualfree: is_manualfree is_deprecated: is_deprecated + is_exported: is_exported is_direct_arr: is_direct_arr is_pub: is_pub is_variadic: is_variadic