compiler: make package exports self-contained
This commit is contained in:
@@ -631,6 +631,16 @@ eval_def_const(Checker *c, Node *n, u64 *out, int depth)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
check_eval_const(Checker *c, Node *n, const char *owner, u64 *out)
|
||||
{
|
||||
const char *saved = c->cur_mod;
|
||||
c->cur_mod = owner;
|
||||
int ok = eval_def_const(c, n, out, 0);
|
||||
c->cur_mod = saved;
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* stamp_intlit — rewrite a const-folded def rhs in place to the
|
||||
* literal it evaluates to, preserving the node's cexpr-resolved type
|
||||
* so the downstream DATA-row emit width and the invariant checks see
|
||||
@@ -3083,6 +3093,27 @@ check_module_shadow(Checker *c, const char *name, Pos pos,
|
||||
kindstr, name, name);
|
||||
}
|
||||
|
||||
/* Self-contained `.wwi` files can carry the same origin-owned type/const
|
||||
* fact through two direct dependencies (a diamond), or alongside a direct
|
||||
* import of that origin. In strict package mode those compiler-generated
|
||||
* declarations describe one canonical package symbol: reuse the first exact
|
||||
* (module, kind, name) binding so nominal Type pointer identity is preserved.
|
||||
* Raw w6c mode deliberately keeps the historical duplicate diagnostics. */
|
||||
static Sym *
|
||||
same_import_fact(Checker *c, Node *d, const char *mod, Skind kind)
|
||||
{
|
||||
if (!c->sep_mode || d == NULL || !d->imported || !d->export
|
||||
|| mod == NULL || mod[0] == '\0')
|
||||
return NULL;
|
||||
if (kind != SK_TYPE && kind != SK_DEF)
|
||||
return NULL;
|
||||
Sym *s = scope_lookup_in_module(c->cur, mod, d->str);
|
||||
if (s == NULL || s->kind != kind || s->decl == NULL || s->decl == d
|
||||
|| !s->decl->imported || !s->decl->export)
|
||||
return NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
check_file(Checker *c, Node *file)
|
||||
{
|
||||
@@ -3145,9 +3176,14 @@ check_file(Checker *c, Node *file)
|
||||
continue;
|
||||
}
|
||||
if (d->kind != N_TYPEDECL) continue;
|
||||
const char *mod = decl_mod(file, d);
|
||||
Sym *fact = same_import_fact(c, d, mod, SK_TYPE);
|
||||
if (fact != NULL) {
|
||||
d->type = fact->type;
|
||||
continue;
|
||||
}
|
||||
Type *named = type_named(c->a, d->str, NULL);
|
||||
Sym *prev = scope_lookup_local(c->cur, d->str);
|
||||
const char *mod = decl_mod(file, d);
|
||||
if (prev && prev->kind == SK_USE) {
|
||||
/* `use mod; ... type mod = ...;` — promote the
|
||||
* SK_USE to the type symbol but remember it was
|
||||
@@ -3175,6 +3211,8 @@ check_file(Checker *c, Node *file)
|
||||
if (d->kind != N_DEF) continue;
|
||||
c->cur_mod = decl_mod(file, d);
|
||||
const char *mod = decl_mod(file, d);
|
||||
if (same_import_fact(c, d, mod, SK_DEF) != NULL)
|
||||
continue;
|
||||
Sym *prev = scope_lookup_local(c->cur, d->str);
|
||||
if (prev && prev->kind == SK_USE) {
|
||||
prev->kind = SK_DEF; prev->decl = d;
|
||||
@@ -3200,9 +3238,14 @@ check_file(Checker *c, Node *file)
|
||||
break;
|
||||
case N_DEF: {
|
||||
Type *t = resolve_type(c, d->lhs);
|
||||
const char *mod = decl_mod(file, d);
|
||||
Sym *fact = same_import_fact(c, d, mod, SK_DEF);
|
||||
if (fact != NULL) {
|
||||
d->type = fact->type ? fact->type : t;
|
||||
break;
|
||||
}
|
||||
d->type = t;
|
||||
Sym *prev = scope_lookup_local(c->cur, d->str);
|
||||
const char *mod = decl_mod(file, d);
|
||||
if (prev && prev->kind == SK_DEF && prev->decl == d) {
|
||||
/* #141: the foldable stub bound before type-body
|
||||
* resolution; fill in its now-resolved type. */
|
||||
|
||||
@@ -609,4 +609,9 @@ void check_file(Checker*, Node *file);
|
||||
* (eval_enum_value's leaf delegation, emit_defs's DATA-row gate). */
|
||||
int fold_int_literal(Node*, u64*);
|
||||
|
||||
/* Re-evaluate a checked integer constant under the declaration owner's
|
||||
* import scope. The compiler export writer uses this to canonicalize array
|
||||
* dimensions without serializing source-level constant dependencies. */
|
||||
int check_eval_const(Checker*, Node*, const char *owner, u64*);
|
||||
|
||||
#endif /* WW_H */
|
||||
|
||||
Reference in New Issue
Block a user