Consts and RTTI are demand-emitted, so under emit-everywhere `cg` the same
external-linkage data definition lands in several modules' .c.nif as `cdata`
(raw text, not droppable) -> multiple definition at link. Procs already
deduped via the `'u'` cdef flag; data now gets the same droppable+owner
treatment, with one difference: data is never DCE'd (RTTI needs pointer
identity for `of`/exception checks; static-per-TU would break that), so it is
always a liveness root and kept by its single owner regardless of liveness.
- New `'d'` cdef flag = a data definition: the merge stage assigns it one
owner (smallest claimant, like `'u'`) and roots it (so its body keeps the
procs it references live); emit keeps the body only in the owner, every
other module keeps just an always-emitted `extern` declaration (the data
analogue of a proc prototype).
- genConstDefinition (ccgexprs) and genTypeInfoV2Impl (ccgtypes) now, under
cmdNifC, emit an extern declaration + wrap the definition in a `'d'` cdef
directive. The RTTI forward decl becomes a real `extern` (was a tentative
definition that would collide across TUs).
- cnif: computeLiveFromCArtifacts, computeMergeDecision and
renderCFromArtifact all handle `'d'`.
icFormatVersion 4 -> 5 (old .c.nif lack the data wrappers).
Validated on the 3-module diamond: the full per-module pipeline (cg all,
merge, emit all, cc, link) now LINKS with no duplicate symbols -- RTTI
(NTIv2) and const tables each land in exactly one object. Whole-program IC
path unchanged (koch ic thallo/tconverter/tmiscs green). Remaining: NimMain
init orchestration (a/b module inits not yet called from main's cg -> the
linked exe runs but prints defaults), the next unit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>