summary_stage-c-cleanup.md 2.5 KB

Stage C cleanup — dead forward-variable text-patching

Tag v3-stage-c-cleanup, branch stage-c-cleanup (off generics-inc1). Suite 189/189; fixpoint OK (3,424,520 bytes).

What was deleted (dead)

The L7 flip made Lower resolve forward designators by name at lower time, so the QbeGen text-patching that rewrote placeholder symbols in the buffered image became unreachable:

  • FwdPatchAll was driven by fwdSite[k], set only by QbeGen.FwdPatch — which had no callers (FwdDesignator/FwdAddrOper were already gone), and nFwd was never incremented.
  • So FwdPatchAll and everything it alone called was dead.

Deleted from QbeGen.mod (146 lines total with the SymTab trim): FwdMangle, FixLoadClass, FixStoreClass, BufReplaceAll, FwdPatchAll, the nFwd/dbgFwd/fwdSite/fwdOper/fwdGlob vars, and the FwdPatchAll; call in EndModule.

Deleted from SymTab.mod: the dead FwdVarName1 wrapper.

No QbeGen.def exports existed for any of these.

What remains, and why (live, not dead)

The grammar/SymTab half is load-bearing and was not deleted:

Symbol Role
SymTab.FwdVarRef a not-yet-declared module global referenced inside a body becomes a placeholder, so parsing does not report 201 prematurely
SymTab.FwdVarName/FwdVarType/FwdVarResolve module-end check: still undeclared ⇒ 201
SymTab.IsFwdVar parse-time leniency (the placeholder is ClPtr-typed, so type checks must not reject it)
grammar FwdVarNote/FwdVarFlush records forward refs; runs the 201 check at module end
grammar Design forward branch emits the @ marker (AST op=1); Lower then resolves it by name

The reason this half survives is the same finding that merged Stage B into Stage C: parse-time checks run before a module's later declarations exist. The AST/Lower pass resolves the reference afterwards, but the tolerance and the 201 reporting still have to happen during parse. Removing them needs the dedicated resolve/check pass (see docs/plan-two-phase.md §2, step 2), which is not built.

Correctness

The image got smaller (3,554,237 → 3,424,520 bytes) and byte-stable across the fixpoint, confirming the deleted code was never executed.

Still open (unchanged)

  • L7 item 7 (SaveSession/RestoreSession/SetNoEmit) — blocked on the grammar's last suppressed writers.
  • The resolve/check pass, which would also let FwdVar*/IsFwdVar go.