336336 inlined_c_typedef_names map[string]bool
337337 inlined_c_fns map[string]bool
338338 inlined_c_declared_fns map[string]bool
339+ inlined_c_active_macros map[string]bool
339340 possibly_active_c_macros map[string]bool
340341 inlined_c_static_fns map[string]bool
341342 cache_omitted_c_fns map[string]bool
@@ -1029,6 +1030,7 @@ pub fn FlatGen.new() FlatGen {
10291030 inlined_c_structs: map[string]bool{}
10301031 inlined_c_fns: map[string]bool{}
10311032 inlined_c_declared_fns: map[string]bool{}
1033+ inlined_c_active_macros: map[string]bool{}
10321034 possibly_active_c_macros: map[string]bool{}
10331035 inlined_c_static_fns: map[string]bool{}
10341036 cache_omitted_c_fns: map[string]bool{}
@@ -2615,6 +2617,7 @@ pub fn (mut g FlatGen) gen_with_used_options(a &flat.FlatAst, used_fns map[strin
26152617 g.inlined_c_structs.clear()
26162618 g.inlined_c_fns.clear()
26172619 g.inlined_c_declared_fns.clear()
2620+ g.inlined_c_active_macros.clear()
26182621 g.possibly_active_c_macros.clear()
26192622 g.inlined_c_static_fns.clear()
26202623 g.cache_omitted_c_fns.clear()
@@ -3377,6 +3380,9 @@ fn (mut g FlatGen) cache_user_c_string_symbols() map[string]bool {
33773380 for name in g.inlined_c_declared_fns.keys() {
33783381 collect_cache_numbered_string_symbols(name, mut symbols)
33793382 }
3383+ for name in g.inlined_c_active_macros.keys() {
3384+ collect_cache_numbered_string_symbols(name, mut symbols)
3385+ }
33803386 referenced_symbols := g.c_extern_referenced_symbols()
33813387 for name in referenced_symbols.keys() {
33823388 collect_cache_numbered_string_symbols(name, mut symbols)
@@ -4675,10 +4681,23 @@ fn (mut g FlatGen) collect_preserved_header_file_with_state_and_scope(path strin
46754681 if collect_declarations {
46764682 g.collect_inlined_c_structs(final_scan.text)
46774683 g.collect_inlined_c_fns(final_scan.text)
4678- g.collect_inlined_c_declared_fns(final_scan.text)
4684+ g.collect_inlined_c_declarations(final_scan.text)
4685+ for macro_name in final_scan.macro_names {
4686+ if final_scan.final_state.defined[macro_name] {
4687+ g.inlined_c_active_macros[macro_name] = true
4688+ g.possibly_active_c_macros.delete(macro_name)
4689+ } else if final_scan.final_state.undefined[macro_name] {
4690+ g.inlined_c_active_macros.delete(macro_name)
4691+ g.possibly_active_c_macros.delete(macro_name)
4692+ } else {
4693+ g.inlined_c_active_macros.delete(macro_name)
4694+ g.possibly_active_c_macros[macro_name] = true
4695+ }
4696+ }
46794697 }
46804698 for macro_name in final_scan.possibly_active_macro_names {
4681- if macro_name !in g.inlined_c_declared_fns {
4699+ if macro_name !in final_scan.final_state.undefined
4700+ && macro_name !in g.inlined_c_active_macros && macro_name !in g.inlined_c_declared_fns {
46824701 g.possibly_active_c_macros[macro_name] = true
46834702 }
46844703 }
@@ -4701,6 +4720,7 @@ struct CHeaderActiveScan {
47014720 include_keys []string
47024721 include_args []string
47034722 include_definitely_active []bool
4723+ macro_names []string
47044724 possibly_active_macro_names []string
47054725 final_state CHeaderMacroState
47064726}
@@ -4853,6 +4873,7 @@ fn c_header_definitely_active_scan_with_include_results(text string, state CHead
48534873 mut include_keys := []string{}
48544874 mut include_args := []string{}
48554875 mut include_definitely_active := []bool{}
4876+ mut macro_names := map[string]bool{}
48564877 mut possibly_active_macro_names := map[string]bool{}
48574878 mut output := strings.new_builder(text.len)
48584879 mut in_block_comment := false
@@ -4950,6 +4971,9 @@ fn c_header_definitely_active_scan_with_include_results(text string, state CHead
49504971 parts := c_directive_arg(clean).fields()
49514972 if parts.len > 0 {
49524973 macro_name := parts[0].all_before('(')
4974+ if possibly_active && macro_name.len > 0 {
4975+ macro_names[macro_name] = true
4976+ }
49534977 if name == 'define' && possibly_active && macro_name.len > 0 {
49544978 possibly_active_macro_names[macro_name] = true
49554979 }
@@ -5010,6 +5034,7 @@ fn c_header_definitely_active_scan_with_include_results(text string, state CHead
50105034 include_keys: include_keys
50115035 include_args: include_args
50125036 include_definitely_active: include_definitely_active
5037+ macro_names: macro_names.keys()
50135038 possibly_active_macro_names: possibly_active_macro_names.keys()
50145039 final_state: CHeaderMacroState{
50155040 defined: defined
@@ -8103,6 +8128,27 @@ fn c_strip_comments(text string) string {
81038128}
81048129
81058130fn (mut g FlatGen) collect_inlined_c_declared_fns(text string) {
8131+ g.collect_inlined_c_declarations(text)
8132+ // Inlined source text has not gone through the active-branch scanner. Keep
8133+ // every visible definition conservative, as before; only preserved headers
8134+ // can use their final preprocessor state to prove that a later #undef wins.
8135+ for line in c_strip_comments(text).split_into_lines() {
8136+ clean := line.trim_space()
8137+ if clean.len == 0 || clean[0] != `#` || c_directive_name(clean) != 'define' {
8138+ continue
8139+ }
8140+ arg := c_directive_arg(clean)
8141+ mut name_end := 0
8142+ for name_end < arg.len && c_ident_char(arg[name_end]) {
8143+ name_end++
8144+ }
8145+ if name_end > 0 {
8146+ g.inlined_c_active_macros[arg[..name_end]] = true
8147+ }
8148+ }
8149+ }
8150+
8151+ fn (mut g FlatGen) collect_inlined_c_declarations(text string) {
81068152 // Header declarations often span several lines (one parameter per line);
81078153 // accumulate a pending declaration until its terminating `;` so those are
81088154 // collected too, not just single-line prototypes.
@@ -8112,19 +8158,6 @@ fn (mut g FlatGen) collect_inlined_c_declared_fns(text string) {
81128158 for name in c_macro_declared_fn_names(clean) {
81138159 g.inlined_c_declared_fns[name] = true
81148160 }
8115- if clean.len > 0 && clean[0] == `#` && c_directive_name(clean) == 'define' {
8116- // Any macro (object- or function-like) named like a `fn C.x` makes
8117- // an emitted extern prototype wrong after preprocessing; the
8118- // header's definition is authoritative.
8119- arg := c_directive_arg(clean)
8120- mut name_end := 0
8121- for name_end < arg.len && c_ident_char(arg[name_end]) {
8122- name_end++
8123- }
8124- if name_end > 0 {
8125- g.inlined_c_declared_fns[arg[..name_end]] = true
8126- }
8127- }
81288161 if pending.len > 0 {
81298162 if clean.len == 0 || clean[0] == `#` || clean.contains('{') || clean.contains('}')
81308163 || pending.len > 4096 {
0 commit comments