mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
feat(phase-31): pregate_check sees brace-bodied externs (the D_80072780 clash that cost a rebuild); §183 addendum
This commit is contained in:
@@ -17976,3 +17976,9 @@ more. `pregate_check`'s CONFLICTING-EXTERN scan should have caught the `D_800727
|
||||
of them and did not: its declaration regex is single-line, and the offending declaration was a
|
||||
multi-line `extern struct { ... } *D_x;`. **A pre-gate check that sees 90% of declarations converts a
|
||||
one-rebuild-per-conflict loop into a single pass — that is where the leverage is, not in the drafting.**
|
||||
**Shipped the same session**: `pregate_check` now scans brace-bodied externs (`extern struct { ... }
|
||||
*D_x;`) with the normalized body as part of the signature, so two identical struct declarations stay
|
||||
silent while a struct-vs-`void *` clash FAILs. Negative-controlled four ways — and one of those
|
||||
controls caught a trap worth its own line: **a synthetic test using a fake symbol name (`D_x`) reported
|
||||
CLEAN for a conflict the tool does detect**, because `sym_of` only recognizes real project symbol
|
||||
spellings. A negative control must use names the system would accept, or it tests nothing.
|
||||
|
||||
@@ -62,6 +62,11 @@ def _depth_map(masked):
|
||||
return out
|
||||
|
||||
|
||||
STRUCT_EXTERN = re.compile(
|
||||
r'^[ \t]*extern\s+(?:const\s+|volatile\s+)*(struct|union)\s*\{([^{}]*)\}\s*(\**)\s*(\w+)\s*(?:\[[^\]]*\])?\s*;',
|
||||
re.M | re.S)
|
||||
|
||||
|
||||
def _norm_sig(sig):
|
||||
"""`void f()` and `void f(void)` are not a conflict worth blocking a rebuild over: C89 calls
|
||||
the first an unspecified parameter list, and gcc-2.7.2 accepts the pair. Normalize both to
|
||||
@@ -155,6 +160,18 @@ def check_text(path, text):
|
||||
|
||||
# 4. one symbol declared two incompatible ways anywhere in the final text
|
||||
decls = {}
|
||||
# BRACE-BODIED EXTERNS FIRST (P31 S53). gm.DECL is single-line, so a draft declaring
|
||||
# extern struct { u8 pad[0x34]; s32 (*field_0x34)(s32); } *D_80072780;
|
||||
# was invisible to this check while a sibling declared the same symbol `void *` — the clash
|
||||
# surfaced only as a compile error, one rebuild later (§183.5). Bodies are flat here (no nested
|
||||
# braces), and the normalized body is part of the signature so two IDENTICAL struct declarations
|
||||
# do not read as a conflict.
|
||||
for m in STRUCT_EXTERN.finditer(masked):
|
||||
if depth[m.start()]:
|
||||
continue
|
||||
body = ' '.join(m.group(2).split())
|
||||
sig = (f'{m.group(1)}{{{body}}}{m.group(3)}', '')
|
||||
decls.setdefault(m.group(4), (m.start(), sig))
|
||||
for m in gm.DECL.finditer(text):
|
||||
if depth[m.start()]: # block-scope decl: private to its function
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user