|
|
@@ -0,0 +1,54 @@
|
|
|
+# 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.
|