comesfrom
nimony/src/lib/comesfrom.nim
Expansion provenance encoded in a line-info filename.
Code produced by expanding a template does not get its own wrapper node. Instead the tokens carry a forged filename that records what they came from, so a debug backend can emit them as DWARF inlined frames:
__crucial\0setElem.0.foo\1foo.nim\116\0[]=.0.system\1system.nim\134\0system.nim ^prefix ^-------- outermost -------^ ^--------- innermost --------^ ^real file
The chain runs outermost-first, so its length is the inlining depth. Each entry is <sym>\1<declfile>\1<declline>: the symbol names the expanded routine, and the declaration site is carried because it cannot be recovered later - a template declaration does not survive into the backend, and the expanded code's own line info points at wherever the body came from, not at the template. Everything after the last NUL is the real filename, which is what a consumer that does not care about frames should use.
A filename cannot otherwise contain a NUL or a \1, which is what makes the encoding unambiguous - note that | would not do, since Nim lets an operator be named |. nifbuilder.needsEscape covers c < ' ', so both control characters survive text NIF as \00 / \01; bif writes filenames length-prefixed, so binary is fine.
Deliberately free of any NIF dependency: it is plain string handling, so the front end, the C backend and the LLVM backend can all reach it without pulling in a cursor API.
const CrucialPrefix: stringMarks a forged filename that carries template-expansion provenance.
const CrucialFieldSep: charSeparates
<sym>,<declfile>and<declline>inside one chain entry.type CrucialOrigin = object sym: string declFile: string declLine: int32
proc isCrucialFile(fname: string): boolTrue when
fnamecarries expansion provenance rather than being a plain source path. Cheap enough to call per token: the\0at the end of the prefix is checked first, and a real path never has one.proc addCrucialInfo(dest: var string; sym: string; declFile: string; declLine: int32)Append one expansion entry to a forged filename under construction. Entries are written outermost first; what follows the last one is the real filename.
deststarts asCrucialPrefix, so building a name isvar f = CrucialPrefix f.addCrucialInfo(sym, declFile, declLine) f.add crucialTail(oldName)
which prepends onto whatever chain
oldNamealready had without parsing it back out.proc crucialTail(fname: string): stringEverything of
fnamethat followsCrucialPrefix: its existing entries plus the real filename, in the exact form they must keep. For a plain filename that is the name itself, so appending this after some entries works whether or notfnamewas already forged.proc realFile(fname: string): stringThe actual source file, with any expansion provenance stripped. Returns
fnameunchanged when it carries none, so every consumer can call it.iterator crucialOrigins(fname: string): CrucialOriginThe expanded routines
fnamecame from, outermost first. Yields nothing for a plain filename.