wcc/ww: mangle imported symbols on dotted import path (#22 M1, #32)

Switch symbol mangling from the import leaf clause to the full dotted import path for directory packages; single-file imports keep package-clause mangling (isdir-gate: imported<=>directory-import). The root build unit's fn main stays bare, every other top-level decl mangles, closing #31's duplicate-main hazard by construction (#32). Both stages, byte-identical.

Single commit, not split: the bare rename (f244af3) is red on its own because it unmasks cross-module resolution gaps that do not reproduce pre-M1, so the fixes are intrinsic to making the rename correct. Included: wwstage fnret/fnparamslookupmod map import alias->path (#199b cross-module union-variant scrutinee resolved the wrong fn's union); cstage use_path prefers the referencing module's import for an ambiguous leaf alias (sha256 crypto.math vs strconv math). Tests table-driven: 989_m1mangle_run/_sym, 989_m1union_run (gate-visible per-arm exit codes + cs==ww byte-id).
This commit is contained in:
2026-06-15 17:37:18 +09:00
parent 64d6c15e41
commit f308818b4b
30 changed files with 1851 additions and 241 deletions

View File

@@ -184,6 +184,10 @@ typedef enum {
* curmod to NULL before a package-less file's bytes
* (#16 option-B; the package-less-entry attribution fix
* that replaces the withdrawn `package main` inject). */
TK_MODPATH, /* `//ww:module <dotted-path>` — driver import boundary:
* the following file's decls mangle on the full import
* path, not the leaf `package` clause (M1 #22). Token
* text carries the dotted path. */
TK_LAST /* sentinel for tables */
} Tkind;
@@ -214,6 +218,9 @@ struct Lex {
int modreset; /* a `//ww:module-reset` directive was seen in
* the last skipped run; lexnext emits TK_MODRESET
* before the next real token. */
const char *modpath; /* a `//ww:module <path>` directive was seen in
* the last skipped run; lexnext emits TK_MODPATH
* carrying this dotted path (M1 #22). */
};
void lexinit(Lex*, Arena*, const char *file, const char *src, u64 len);
@@ -340,7 +347,17 @@ struct Node {
* decl's section in combined.ww.
* NULL for nested nodes; only top-
* level decls (fn/def/type/let)
* carry it. */
* carry it. On an N_USE node this is
* the importing (owning) module. */
const char *usepath; /* M1 #22: on an N_USE node, the full
* dotted IMPORT path (`encoding.utf8`)
* vs the leaf alias in `str`. Drives
* the path-keyed decl_mod match and the
* qualified-ref codegen hint. */
int imported; /* M1 #22: decl reached through an
* `//ww:module <path>` import boundary
* (vs root/primary). Gates the root-only
* bare-`main` rule (#32). */
};
Node *newnode(Arena*, Nkind, Pos);
@@ -358,6 +375,10 @@ struct Parser {
const char *curmod; /* most-recent `module foo;` declaration —
* stamped onto each top-level decl that
* follows. */
const char *pathmod; /* M1 #22: active `//ww:module <path>` dotted
* import path; while set, decls stamp
* module=pathmod and imported=1, and the
* in-file `package` clause is an assertion. */
};
void parserinit(Parser*, Arena*, Lex*);