selfhost: structlookup/enumlookup mod-filter (mirror aliaslookup)
Tags structinfo/enumtype with originating module; exact-match first, then split pkg.X and filter by smod/emod. Without this, two modules with same-leaf-name struct/enum types collapsed to whichever entry appeared first in the chain. Wired into 696_modtype_leaf_collision via a wwstage run_pos using ww_ww (negative case omitted: w6c_ww has no checkfile pass). Updated the test's Makefile deps to include the wwstage binaries. Audited the rest of the lookup family — fnretlookup, fnparamslookup, deflookup don't need the same treatment: the parser emits N_DOT.str (call/field name) as the leaf only, and fnparamslookup is only invoked with N_IDENT.str. Dotted module-qualified function calls go through the module-mangling path instead.
This commit is contained in:
@@ -179,8 +179,9 @@ fn collectenums(c: *cgen, file: *node) void = {
|
||||
let body: *node = d.lhs;
|
||||
if (body != nil) {
|
||||
if (body.kind == nkind.N_TENUM) {
|
||||
let et: *enumtype = amalloc(c.a, 48u64): *enumtype;
|
||||
let et: *enumtype = amalloc(c.a, 64u64): *enumtype;
|
||||
et.ename = d.str;
|
||||
et.emod = d.module;
|
||||
et.storage = body.lhs;
|
||||
et.members = nil;
|
||||
let prev: u64 = (-1i64): u64;
|
||||
@@ -216,24 +217,40 @@ fn collectenums(c: *cgen, file: *node) void = {
|
||||
};
|
||||
|
||||
fn enumlookup(c: *cgen, name: str) *enumtype = {
|
||||
// Strip any `pkg.` prefix and key off the leaf — driver-side
|
||||
// concatenation flattens the namespace, so `os.whence` and
|
||||
// `whence` refer to the same registered enum.
|
||||
let leaf: str = name;
|
||||
// Exact match first: bare-from-source idents and already-leafed
|
||||
// names hit here directly.
|
||||
let e: *enumtype = c.enums;
|
||||
for (e != nil) {
|
||||
if (streq(e.ename, name)) { return e; };
|
||||
e = e.etnext;
|
||||
};
|
||||
// Module-qualified form: `pkg.enum` → match the leaf scoped to
|
||||
// its originating module. Mirrors aliaslookup's mod-filter; the
|
||||
// `emod == pkg` guard is what prevents two modules with same-
|
||||
// leaf-name enums from collapsing into whichever entry appears
|
||||
// first in the chain.
|
||||
let i: i32 = name.len - 1;
|
||||
for (i >= 0) {
|
||||
if (name[i] == 46u8) { // '.'
|
||||
leaf.ptr = name.ptr + (i + 1): u64;
|
||||
let pkg: str;
|
||||
pkg.ptr = name.ptr;
|
||||
pkg.len = i;
|
||||
let leaf: str;
|
||||
leaf.ptr = name.ptr + ((i + 1): u64);
|
||||
leaf.len = name.len - (i + 1);
|
||||
break;
|
||||
let b: *enumtype = c.enums;
|
||||
for (b != nil) {
|
||||
if (streq(b.ename, leaf)) {
|
||||
if (streq(b.emod, pkg)) {
|
||||
return b;
|
||||
};
|
||||
};
|
||||
b = b.etnext;
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
i -= 1;
|
||||
};
|
||||
let e: *enumtype = c.enums;
|
||||
for (e != nil) {
|
||||
if (streq(e.ename, leaf)) { return e; };
|
||||
e = e.etnext;
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
@@ -283,6 +300,7 @@ type fieldinfo = struct {
|
||||
|
||||
type structinfo = struct {
|
||||
sname: str,
|
||||
smod: str, // originating module (`// MODULE: foo`), or empty
|
||||
fields: *fieldinfo,
|
||||
totsize: i32,
|
||||
sinext: *structinfo,
|
||||
@@ -326,6 +344,7 @@ type enummember = struct {
|
||||
|
||||
type enumtype = struct {
|
||||
ename: str,
|
||||
emod: str, // originating module (`// MODULE: foo`), or empty
|
||||
storage: *node, // AST type expr for the storage type (i32 by default)
|
||||
members: *enummember,
|
||||
etnext: *enumtype,
|
||||
|
||||
Reference in New Issue
Block a user